﻿#include "CenterWidget.h"
#include "ui_CenterWidget.h"

#include <QHBoxLayout>
#include <QStandardItemModel>
#include <QLabel>
#include <QVBoxLayout>
#include <QMenu>
#include <QHeaderView>

#include "QPushButton.h"
#include "QScrollArea.h"
#include "QTabWidget.h"
#include "QScrollBar.h"
#include "QTreeView.h"
#include "QTextEdit.h"

#include "BaseModule/IBaseSignal.h"

#include "qcustomplot.h"
#include "Graph2DWindowBase.h"
#include "LineChartWindow.h"
#include "HeatMapWindow.h"
#include "PolarCoordinateGraphWindow.h"
#include "Graph3DWindowBase.h"
#include "SurfaceElectricFieldMapWindow.h"
#include "ThreeDCloudMapWindow.h"
#include "ThreeDSurfacePlotWindow.h"
// #include "GraphSurface.h"
#include <vtkTable.h>
#include <vtkPointSet.h>
#include <vtkDoubleArray.h>
#include "TextFileParser.h"
#include "BaseWidget/IdaDialogMsg.h"
#include "BaseWidget/IWidgetSignal.h"
#include "SurfaceElectricFieldMapSelectDataDialog.h"
#include "PostCommand/PostCommandPy.h"
#include "TableDisplayWindow.h"
#include "AnimationSettingData.h"
#include "HeatMapWindow.h"
#include "DataManager/ProjectTreeData.h"
#include "DataManager/WindowTotalData.h"
#include <QMetaProperty>

#include "TableChatWindow.h"

#include <QRegularExpression>

namespace pst
{

    CenterWidget::CenterWidget(QWidget* parent)
        : QWidget(parent), ui(new Ui::CenterWidget()), m_animationSettingData(new AnimationSettingData(this)), m_heatMapWindowList{}
    {
        ui->setupUi(this);

        // 用于样式
        setObjectName("m_centerWidget");
        setAttribute(Qt::WA_StyledBackground);

        // this->setStyleSheet("{background-color: #FFFFFF}");
        // QWidget* centralWidget = new QWidget(this);
        // QHBoxLayout* centerVLayout = new QHBoxLayout(centralWidget);
        // centerVLayout->setContentsMargins(0, 0, 0, 0);
        // centerVLayout->setSpacing(8);

        // ------------------ 后处理窗口的选项卡视图
        // ui->tabWidget = new QTabWidget(this);
        // ui->tabWidget->setObjectName("tabWidget");
        // ui->tabWidget->setSizePolicy(QSizePolicy::Policy::Expanding, QSizePolicy::Policy::Expanding);
        // 创建二维视图
        //_graph2D = new Graph2D(ui->tabWidget);
        // ui->tabWidget->addTab(_graph2D, "图1");
        // 创建三维视图
        // auto _threeDimensionDiagraph = new pst::ThreeDimensionDiagraph(this);
        // ui->tabWidget->addTab(_threeDimensionDiagraph, "图2");

        // ------------------ 项目树
        // 创建项目树的模型
        treeModel = new QStandardItemModel();
        // QStandardItem* _itemParent = new QStandardItem(QString("工程1"));
        //_itemParent->setCheckable(false);
        // model->appendRow(_itemParent);
        // for (int i = 0; i < 5; i++)
        //{
        //     QStandardItem* _itemParent = new QStandardItem(QString("工程%1").arg(i));
        //     _itemParent->setCheckable(false);
        //     for (int j = 0; j < 6; j++)
        //     {
        //         QStandardItem* _itemChild = new QStandardItem(QString("数据%1").arg(i));
        //         _itemChild->setCheckable(false);
        //         _itemParent->appendRow(_itemChild);
        //     }
        //     model->appendRow(_itemParent);
        //     model->item(0)->appendRow(new QStandardItem(QString("数据")));
        // }
        // model->setHeaderData(0, Qt::Horizontal, "数据展示", Qt::DisplayRole);

        // ui->treeView = new QTreeView(this);
        // 设置滚动条
        // QScrollBar* treeViewFloatScrollBar = new QScrollBar(ui->treeView);
        // treeViewFloatScrollBar->setIsAnimation(true);
        // 设置标题
        // QFont headerFont = ui->treeView->header()->font();
        // headerFont.setPixelSize(16);
        // ui->treeView->header()->setFont(headerFont);
        ui->treeView->setModel(treeModel);
        // ui->treeView->setSizePolicy(QSizePolicy::Policy::Preferred, QSizePolicy::Policy::Expanding);
        ui->treeView->expandAll();
        ui->treeView->header()->setHidden(true); // 行名隐藏
        ProjectTreeDataInstance->setTreeView(ui->treeView);

        // 连接信号与槽
        connect(ui->treeView, &QTreeView::customContextMenuRequested, this, &CenterWidget::showContextMenu);
        ui->treeView->setContextMenuPolicy(Qt::CustomContextMenu); // 设置上下文菜单策略

        connect(ui->treeView->selectionModel(), &QItemSelectionModel::selectionChanged, this, [this]()
                {
                    auto items = getSelectedItems();
                    emit signal_fileClicked(items); 
                    QStringList _itemIDList{};
                    for (auto _item : items)
                    {
                        auto _itemId = _item->data(Qt::UserRole + 10);
                        if (_itemId.isNull())
                            return;
                        _itemIDList.append(_itemId.toString());
                    }
                    if (_itemIDList.count() > 1) // 目前只允许项目树单选节点
                        return; 
                    QString _rowListStr = _itemIDList.join(",");
                    QString _pyCommand = QString("PostProcessing.projectTreeSelectionChanged('%1')").arg(_rowListStr);
                    emit IBaseSignalInstance->signal_execPYCode(QStringList(_pyCommand), true, false); 
                });

        // 设置宽度比例
        ui->splitter->setSizes({100, 600});

        disconnect(ui->tabWidget->tabBar(), &QTabBar::tabCloseRequested, 0, 0);
        connect(ui->tabWidget->tabBar(), &QTabBar::tabCloseRequested, this, &CenterWidget::on_tabWidget_tabCloseRequested);
        connect(ui->tabWidget->tabBar(), &QTabBar::tabBarClicked, this, &CenterWidget::on_tabWidget_tabClicked);
        ui->tabWidget->setTabsClosable(true);
        connect(ui->tabWidget->tabBar(), &QTabBar::currentChanged, this, &CenterWidget::signal_currentWindowChanged);


        ////将项目树和后处理窗口添加到中间视图
        // QSplitter* splitter = new QSplitter(Qt::Horizontal, centralWidget);
        ////splitter->setContentsMargins(0, 0, 0, 0);
        // splitter->addWidget(ui->treeView);
        // splitter->addWidget(ui->tabWidget);
        // splitter->setSizes({ 100,600 });
        // centerVLayout->addWidget(splitter);
        // addCentralWidget(centralWidget, true, false, 0);

        connect(IBaseSignalInstance, &BaseWidget::IWidgetSignal::signal_lineChartCenterWidgetInfoListPaste, this, [this](QString infoIds)
                {
                        if(!this->isVisible())return;
                        QList<Info2DPointer> infoList;
                        QList<QString> infoIdList = infoIds.split(",");

                        for (QString id :infoIdList)
                        {
                            int infoID = id.toInt();

                            Info2DPointer infoPtr = WindowTotalDataInstance->getInfomationCurve2DBasicalByID(infoID);

                            InfomationCurve2DBasical info = *infoPtr;
                            QSharedPointer<InfomationCurve2DBasical> newInfoPtr = Info2DPointer(new InfomationCurve2DBasical(info));

                            infoList.append(newInfoPtr);
                        }
                        addImageToNewGrapg2DWindow(infoList, false);
            });

        

        
        connect(ui->tabWidget->tabBar(), &QTabBar::currentChanged, this, [this](){
            QString _pyCommand = QString("PostProcessing.centerWidgetTabWidgetCurrentChanged(%1)").arg(ui->tabWidget->currentIndex());
            emit IBaseSignalInstance->signal_execPYCode(QStringList(_pyCommand), true, false); 
        });

        connect(IBaseSignalInstance, &BaseWidget::IWidgetSignal::signal_centerWidgetTabWidgetCurrentChanged, this, [this](int currentIndex)
        {
                if(!this->isVisible())return;
                ui->tabWidget->setCurrentIndex(currentIndex);
                        
        });


        initConnect();
    }

    void CenterWidget::initConnect()
    {
        WindowTotalDataInstance;
        PostCommandManagerPyInstance;//初始化脚本信号连接
        connect(IBaseSignalInstance, &BaseWidget::IWidgetSignal::signal_pasteFileItemData, this, &CenterWidget::slot_pasteFileItemData);
        connect(IBaseSignalInstance, &BaseWidget::IWidgetSignal::signal_pasteDirectoryItemData, this, &CenterWidget::slot_pasteDirectoryItemData);
        connect(IBaseSignalInstance, &BaseWidget::IWidgetSignal::signal_projectTreeSelectionChanged, this, &CenterWidget::slot_projectTreeSelectionChanged);
        connect(IBaseSignalInstance, &BaseWidget::IWidgetSignal::signal_saveGraph, this, &CenterWidget::slot_saveScreenShot);
        connect(IBaseSignalInstance, &BaseWidget::IWidgetSignal::signal_setHeatMapSelectedCurveNameIndexs, this, &CenterWidget::slot_setHeatMapSelectedCurveNameIndexs);
        connect(IBaseSignalInstance, &BaseWidget::IWidgetSignal::signal_setHeatMapVariableAxisChanged, this, &CenterWidget::slot_setHeatMapVariableAxisChanged);
        connect(IBaseSignalInstance, &BaseWidget::IWidgetSignal::signal_setHeatMapSecondVariableAxisChanged, this, &CenterWidget::slot_setHeatMapSecondVariableAxisChanged);
        connect(IBaseSignalInstance, &BaseWidget::IWidgetSignal::signal_setHeatMapCurveNameCheckStateChanged, this, &CenterWidget::slot_setHeatMapCurveNameCheckStateChanged);
        connect(IBaseSignalInstance, &BaseWidget::IWidgetSignal::signal_setHeatMapDataOprationChanged, this, &CenterWidget::slot_setHeatMapDataOprationChanged);
        connect(IBaseSignalInstance, &BaseWidget::IWidgetSignal::signal_setHeatMapResultValueDataChanged, this, &CenterWidget::slot_setHeatMapResultValueDataChanged);
        connect(IBaseSignalInstance, &BaseWidget::IWidgetSignal::signal_saveHeatMapMainSettingData, this, &CenterWidget::slot_saveHeatMapMainSettingData);
        connect(IBaseSignalInstance, &BaseWidget::IWidgetSignal::signal_setHeatMapFixedValueChanged, this, &CenterWidget::slot_setHeatMapFixedValueChanged);
        connect(IBaseSignalInstance, &BaseWidget::IWidgetSignal::signal_setHeatMapComplexPartsChanged, this, &CenterWidget::slot_setHeatMapComplexPartsChanged);
        connect(IBaseSignalInstance, &BaseWidget::IWidgetSignal::signal_setHeatMapRemoveSelectedGraph, this, &CenterWidget::slot_setHeatMapRemoveSelectedGraph);
        connect(IBaseSignalInstance, &BaseWidget::IWidgetSignal::signal_setHeatMapRenameFinished, this, &CenterWidget::slot_setHeatMapRenameFinished);
        connect(IBaseSignalInstance, &BaseWidget::IWidgetSignal::signal_setHeatMapAddTracer, this, &CenterWidget::slot_setHeatMapAddTracer);
        connect(IBaseSignalInstance, &BaseWidget::IWidgetSignal::signal_setHeatMapRemoveSelectedTracer, this, &CenterWidget::slot_setHeatMapRemoveSelectedTracer);
        connect(IBaseSignalInstance, &BaseWidget::IWidgetSignal::signal_setHeatMapRemoveAllTracer, this, &CenterWidget::slot_setHeatMapRemoveAllTracer);
        connect(IBaseSignalInstance, &BaseWidget::IWidgetSignal::signal_setHeatMapExportMarkerData, this, &CenterWidget::slot_setHeatMapExportMarkerData);
        connect(IBaseSignalInstance, &BaseWidget::IWidgetSignal::signal_setHeatMapChangeTracerProperty, this, &CenterWidget::slot_setHeatMapChangeTracerProperty);

        // 二维折线图
        connect(IBaseSignalInstance, &BaseWidget::IWidgetSignal::signal_lineChartSidebarVariableAxisChanged, this, &CenterWidget::slot_lineChartSidebarVariableAxisChanged);
        connect(IBaseSignalInstance, &BaseWidget::IWidgetSignal::signal_lineChartSidebarCurveNameClicked, this, &CenterWidget::slot_lineChartSidebarCurveNameClicked);
        connect(IBaseSignalInstance, &BaseWidget::IWidgetSignal::signal_lineChartSidebarCurveNameCheckStateChanged, this, &CenterWidget::slot_lineChartSidebarCurveNameCheckStateChanged);
        connect(IBaseSignalInstance, &BaseWidget::IWidgetSignal::signal_lineChartSidebarDataOperationChanged, this, &CenterWidget::slot_lineChartSidebarDataOperationChanged);
        connect(IBaseSignalInstance, &BaseWidget::IWidgetSignal::signal_lineChartSidebarFixedValueChanged, this, &CenterWidget::slot_lineChartSidebarFixedValueChanged);
        connect(IBaseSignalInstance, &BaseWidget::IWidgetSignal::signal_lineChartSidebarValueDataChanged, this, &CenterWidget::slot_lineChartSidebarValueDataChanged);
        connect(IBaseSignalInstance, &BaseWidget::IWidgetSignal::signal_saveLineChartMainSettingData, this, &CenterWidget::slot_lineChartSaveMainSettingData);
        connect(IBaseSignalInstance, &BaseWidget::IWidgetSignal::signal_lineChartWindowAddTracer, this, &CenterWidget::slot_lineChartWindowAddTracer);

        // 极坐标图
        connect(IBaseSignalInstance, &BaseWidget::IWidgetSignal::signal_polarCoordinateGraphSidebarVariableAxisChanged, this, &CenterWidget::slot_polarCoordinateGraphSidebarVariableAxisChanged);
        connect(IBaseSignalInstance, &BaseWidget::IWidgetSignal::signal_polarCoordinateGraphSidebarAllVariableAxisChanged, this, &CenterWidget::slot_polarCoordinateGraphSidebarAllVariableAxisChanged);
        connect(IBaseSignalInstance, &BaseWidget::IWidgetSignal::signal_polarCoordinateGraphSidebarCurveNameClicked, this, &CenterWidget::slot_polarCoordinateGraphSidebarCurveNameClicked);
        connect(IBaseSignalInstance, &BaseWidget::IWidgetSignal::signal_polarCoordinateGraphSidebarCurveNameCheckStateChanged, this, &CenterWidget::slot_polarCoordinateGraphSidebarCurveNameCheckStateChanged);
        connect(IBaseSignalInstance, &BaseWidget::IWidgetSignal::signal_polarCoordinateGraphSidebarDataOperationChanged, this, &CenterWidget::slot_polarCoordinateGraphSidebarDataOperationChanged);
        connect(IBaseSignalInstance, &BaseWidget::IWidgetSignal::signal_polarCoordinateGraphSidebarValueDataChanged, this, &CenterWidget::slot_polarCoordinateGraphSidebarValueDataChanged);
        //connect(IBaseSignalInstance, &BaseWidget::IWidgetSignal::signal_savePolarCoordinateGraphMainSettingData, this, &CenterWidget::slot_polarCoordinateGraphSaveMainSettingData);
        connect(IBaseSignalInstance, &BaseWidget::IWidgetSignal::signal_polarCoordinateGraphSidebarDeleteAllGraph, this, &CenterWidget::slot_polarCoordinateGraphSidebarDeleteAllGraph);
        connect(IBaseSignalInstance, &BaseWidget::IWidgetSignal::signal_polarCoordinateGraphSidebarRenameSelectedGraph, this, &CenterWidget::slot_polarCoordinateGraphSidebarRenameSelectedGraph);
        connect(IBaseSignalInstance, &BaseWidget::IWidgetSignal::signal_polarCoordinateGraphSidebarComplexPartsChanged, this, &CenterWidget::slot_polarCoordinateGraphSidebarComplexPartsChanged);
        connect(IBaseSignalInstance, &BaseWidget::IWidgetSignal::signal_polarCoordinateGraphSidebarFixedValueChanged, this, &CenterWidget::slot_polarCoordinateGraphSidebarFixedValueChanged);
        connect(IBaseSignalInstance, &BaseWidget::IWidgetSignal::signal_polarCoordinateGraphSidebarRemoveSelectedGraph, this, &CenterWidget::slot_polarCoordinateGraphSidebarRemoveSelectedGraph);
        connect(IBaseSignalInstance, &BaseWidget::IWidgetSignal::signal_polarCoordinateGraphSidebarCopySelectedGraph, this, &CenterWidget::slot_polarCoordinateGraphSidebarCopySelectedGraph);
        connect(IBaseSignalInstance, &BaseWidget::IWidgetSignal::signal_polarCoordinateGraphAddTracer, this, &CenterWidget::slot_polarCoordinateGraphAddTracer);
        connect(IBaseSignalInstance, &BaseWidget::IWidgetSignal::signal_polarCoordinateGraphRemoveSelectedTracer, this, &CenterWidget::slot_polarCoordinateGraphRemoveSelectedTracer);
        connect(IBaseSignalInstance, &BaseWidget::IWidgetSignal::signal_polarCoordinateGraphRemoveAllTracer, this, &CenterWidget::slot_polarCoordinateGraphRemoveAllTracer);
        connect(IBaseSignalInstance, &BaseWidget::IWidgetSignal::signal_polarCoordinateGraphExportMarkerData, this, &CenterWidget::slot_polarCoordinateGraphExportMarkerData);
        connect(IBaseSignalInstance, &BaseWidget::IWidgetSignal::signal_polarCoordinateGraphChangeTracerProperty, this, &CenterWidget::slot_polarCoordinateGraphChangeTracerProperty);

        // 三维曲面图
        connect(IBaseSignalInstance, &BaseWidget::IWidgetSignal::signal_threeDSurfacePlotSidebarCurveNameClicked, this, &CenterWidget::slot_threeDSurfacePlotSidebarCurveNameClicked);
        connect(IBaseSignalInstance, &BaseWidget::IWidgetSignal::signal_threeDSurfacePlotSidebarFrequencyChanged, this, &CenterWidget::slot_threeDSurfacePlotSidebarFrequencyChanged);
        connect(IBaseSignalInstance, &BaseWidget::IWidgetSignal::signal_threeDSurfacePlotSidebarResultDataChanged, this, &CenterWidget::slot_threeDSurfacePlotSidebarResultDataChanged);
        connect(IBaseSignalInstance, &BaseWidget::IWidgetSignal::signal_threeDSurfacePlotSidebarDataOprationChanged, this, &CenterWidget::slot_threeDSurfacePlotSidebarDataOprationChanged);
        connect(IBaseSignalInstance, &BaseWidget::IWidgetSignal::signal_threeDSurfacePlotSidebarCurveNameItemCheckStateChanged, this, &CenterWidget::slot_threeDSurfacePlotSidebarCurveNameItemCheckStateChanged);
        connect(IBaseSignalInstance, &BaseWidget::IWidgetSignal::signal_saveThreeDSurfacePlotMainSettingData, this, &CenterWidget::slot_saveThreeDSurfacePlotMainSettingData);
        connect(IBaseSignalInstance, &BaseWidget::IWidgetSignal::signal_saveThreeDSurfacePlotMoveResultDataSetting, this, &CenterWidget::slot_saveThreeDSurfacePlotMoveResultDataSetting);
        connect(IBaseSignalInstance, &BaseWidget::IWidgetSignal::signal_delete3DSurfacePlots, this, &CenterWidget::slot_delete3DSurfacePlots);
        connect(IBaseSignalInstance, &BaseWidget::IWidgetSignal::signal_threeDSurfaceCurveNameItemRename, this, &CenterWidget::slot_threeDSurfaceCurveNameItemRename);
        connect(IBaseSignalInstance, &BaseWidget::IWidgetSignal::signal_threeDSurfaceCurveDataFileterRadioButtonClicked, this, &CenterWidget::slot_threeDSurfaceCurveDataFileterRadioButtonClicked);


        // 三维云图
        connect(IBaseSignalInstance, &BaseWidget::IWidgetSignal::signal_threeDCloudMapSidebarCurveNameClicked, this, &CenterWidget::slot_threeDCloudMapSidebarCurveNameClicked);
        connect(IBaseSignalInstance, &BaseWidget::IWidgetSignal::signal_threeDCloudMapSidebarUpdateFixedParameter, this, &CenterWidget::slot_threeDCloudMapSidebarUpdateFixedParameter);
        connect(IBaseSignalInstance, &BaseWidget::IWidgetSignal::signal_threeDCloudMapSidebarUpdateOriginalDataSource, this, &CenterWidget::slot_threeDCloudMapSidebarUpdateOriginalDataSource);
        connect(IBaseSignalInstance, &BaseWidget::IWidgetSignal::signal_threeDCloudMapSidebarResultDataChanged, this, &CenterWidget::slot_threeDCloudMapSidebarResultDataChanged);
        connect(IBaseSignalInstance, &BaseWidget::IWidgetSignal::signal_threeDCloudMapSidebarNameItemRename, this, &CenterWidget::slot_threeDCloudMapSidebarNameItemRename);
        connect(IBaseSignalInstance, &BaseWidget::IWidgetSignal::signal_threeDCloudMapSidebarDelete3DCloudMap, this, &CenterWidget::slot_threeDCloudMapSidebarDelete3DCloudMap);
        connect(IBaseSignalInstance, &BaseWidget::IWidgetSignal::signal_threeDCloudMapSidebarDataOprationChanged, this, &CenterWidget::slot_threeDCloudMapSidebarDataOprationChanged);
        connect(IBaseSignalInstance, &BaseWidget::IWidgetSignal::signal_threeDCloudMapSidebarItemCheckStateChanged, this, &CenterWidget::slot_threeDCloudMapSidebarItemCheckStateChanged);
        connect(IBaseSignalInstance, &BaseWidget::IWidgetSignal::signal_saveThreeDCloudMapMainSettingData, this, &CenterWidget::slot_saveThreeDCloudMapMainSettingData);

        // 表面电场图
        connect(IBaseSignalInstance, &BaseWidget::IWidgetSignal::signal_surfaceElectricFieldMapSidebarCurveNameClicked, this, &CenterWidget::slot_surfaceElectricFieldMapSidebarCurveNameClicked);
        connect(IBaseSignalInstance, &BaseWidget::IWidgetSignal::signal_surfaceElectricFieldMapSidebarResultDataChanged, this, &CenterWidget::slot_surfaceElectricFieldMapSidebarResultDataChanged);
        connect(IBaseSignalInstance, &BaseWidget::IWidgetSignal::signal_surfaceElectricFieldMapSidebarUpdateProcessData, this, &CenterWidget::slot_surfaceElectricFieldMapSidebarUpdateProcessData);
        connect(IBaseSignalInstance, &BaseWidget::IWidgetSignal::signal_surfaceElectricFieldMapSidebarNameItemRename, this, &CenterWidget::slot_surfaceElectricFieldMapSidebarNameItemRename);
        connect(IBaseSignalInstance, &BaseWidget::IWidgetSignal::signal_surfaceElectricFieldMapSidebarDeleteSurfaceElectricFieldMap, this, &CenterWidget::slot_surfaceElectricFieldMapSidebarDeleteSurfaceElectricFieldMap);
        connect(IBaseSignalInstance, &BaseWidget::IWidgetSignal::signal_surfaceElectricFieldMapSidebarItemCheckStateChanged, this, &CenterWidget::slot_surfaceElectricFieldMapSidebarItemCheckStateChanged);
        connect(IBaseSignalInstance, &BaseWidget::IWidgetSignal::signal_saveSurfaceElectricFieldMapMainSettingData, this, &CenterWidget::slot_saveSurfaceElectricFieldMapMainSettingData);

        //三维图标记
        connect(IBaseSignalInstance, &BaseWidget::IWidgetSignal::signal_savePostMarkerAddSettingData, this, &CenterWidget::slot_savePostMarkerAddSettingData);
        connect(IBaseSignalInstance, &BaseWidget::IWidgetSignal::signal_savePostMarkerRemoveChosenSettingData, this, &CenterWidget::slot_savePostMarkerRemoveChosenSettingData);
        connect(IBaseSignalInstance, &BaseWidget::IWidgetSignal::signal_savePostMarkerRemoveAllSettingData, this, &CenterWidget::slot_savePostMarkerRemoveAllSettingData);
        connect(IBaseSignalInstance, &BaseWidget::IWidgetSignal::signal_savePostMarkerExportTableData, this, &CenterWidget::slot_savePostMarkerExportTableData);

        //波形分析
        connect(IBaseSignalInstance, &BaseWidget::IWidgetSignal::signal_sentWaveButterANdFFTVResult, this, &CenterWidget::slot_sentWaveButterANdFFTVResult);

        QObject::connect(ui->treeView, &QTreeView::expanded, [=](const QModelIndex& index)
        {
                QStandardItem* item = treeModel->itemFromIndex(index);
                auto itemId = item->data(Qt::UserRole + 10).toInt();
                saveCollapseOrExpandPyCode(true, itemId);
        });

        QObject::connect(ui->treeView, &QTreeView::collapsed, [=](const QModelIndex& index)
        {
                QStandardItem* item = treeModel->itemFromIndex(index);
                auto itemId = item->data(Qt::UserRole + 10).toInt();
                saveCollapseOrExpandPyCode(false, itemId);
        });
    }

    void CenterWidget::pyCloseCenterTableBar(int index)
    {
        closeCenterTableBar(index, false);
    }

    void CenterWidget::on_tabWidget_tabCloseRequested(int index)
    {
        if (!m_isCanCloseTab)
            return;
        closeCenterTableBar(index, true);
    }

    void CenterWidget::closeCenterTableBar(int index, bool savePy)
    {
        auto currentWindow = ui->tabWidget->widget(index);
        if (qobject_cast<LineChartWindow*>(currentWindow) != nullptr || qobject_cast<PolarCoordinateGraphWindow*>(currentWindow) != nullptr || qobject_cast<HeatMapWindow*>(currentWindow) != nullptr) // 二维
        {
            auto _window = qobject_cast<Graph2DWindowBase*>(currentWindow);
            WindowTotalDataInstance->removeGraph2DWindow(_window);
        }
        else if (qobject_cast<ThreeDCloudMapWindow*>(currentWindow) != nullptr || qobject_cast<ThreeDSurfacePlotWindow*>(currentWindow) != nullptr || qobject_cast<SurfaceElectricFieldMapWindow*>(currentWindow) != nullptr || qobject_cast<TableChatWindow*>(currentWindow) != nullptr) // 三维
        {
            auto _window = qobject_cast<Graph3DWindowBase*>(currentWindow);
            WindowTotalDataInstance->removeGraph3DWindow(_window);
        }
        else
        {
            // 无图
            return;
        }
        ui->tabWidget->removeTab(index);

        if (savePy)
        {
            QStringList _pyCodes{};
            _pyCodes += QString("appPrj = PostProcessing.AppPrj()");
            _pyCodes += QString("appPrj.closeCenterTableBar(%1)").arg(index);
            emit IBaseSignalInstance->signal_execPYCode(_pyCodes, true, false);
        }

    }


    void CenterWidget::changeCurrentTabBar(int index, bool savePy)
    {
        ui->tabWidget->setCurrentIndex(index);
        if (savePy)
        {
            QStringList _pyCodes{};
            _pyCodes += QString("appPrj = PostProcessing.AppPrj()");
            _pyCodes += QString("appPrj.changeCurrentTabBar(%1)").arg(index);
            emit IBaseSignalInstance->signal_execPYCode(_pyCodes, true, false);
        }
    }

    void CenterWidget::on_tabWidget_tabClicked(int index)
    {
        changeCurrentTabBar(index, true);
    }

    void CenterWidget::pyChangeCurrentTabBar(int index)
    {
        changeCurrentTabBar(index, false);
    }

    void CenterWidget::pySubmitEvaluation(int windowId, int evaluationType, QString parms)
    {
        LineChartWindow*  lineChatWindow = getLineChartWindowByWindowID(windowId);
        lineChatWindow->pySubmitEvaluation(evaluationType, parms);
    }

    CenterWidget::~CenterWidget()
    {
        // for (auto i : m_graph2DList)
        //{
        //     if (i != nullptr)
        //     {
        //         delete i;
        //         i = nullptr;
        //     }
        // }
    }

    QWidget* CenterWidget::getCurrentGraphWindow()
    {
        return ui->tabWidget->currentWidget();
    }

    void CenterWidget::setFileTypeList(QList<bool> list)
    {
        m_is2D = list.at(0);
        m_isPolar = list.at(1);
        m_isSurfaceElectricField = list.at(2);
        m_isTwoDHeatMap = list.at(3);
        m_isThreeDCloudMap = list.at(4);
        m_isThreeDSurfacePlot = list.at(5);
        m_TwoDPeakValleyGraph = list.at(6);
        m_isDataTable = list.at(7);
    }

    // void CenterWidget::showModel(bool isShow)
    //{
    //     auto currentWindow = getCurrentGraphWindow();
    //     if ( qobject_cast<Graph3DWindowBase*>(currentWindow) != nullptr )
    //     {
    //         auto window = qobject_cast<Graph3DWindowBase*>(currentWindow);
    //         window->showGeometryActors(isShow);
    //     }
    // }


    void CenterWidget::pyDoPrjCloseTree(int index)
    {
        auto model = (QStandardItemModel*)ui->treeView->model();
        QModelIndex modelIndex = model->index(index, 0, QModelIndex());
        QStandardItem* item = model->itemFromIndex(modelIndex);
        QList<QStandardItem*> leafs = getLeafsByItem(item);
        emit IWidgetSignalInstance->signal_closeTree(leafs);
        if (!item->data(Qt::UserRole + 10).isNull())
        {
            auto _removeItemID = item->data(Qt::UserRole + 10).toInt();
            ProjectTreeDataInstance->removePasteAndImportItemData(_removeItemID);
        }
        model->removeRow(item->row());
    }

    void CenterWidget::pyDoPrjTreeCopyDir(int index)
    {
        auto model = (QStandardItemModel*)ui->treeView->model();
        QModelIndex modelIndex = model->index(index, 0, QModelIndex());
        QStandardItem* item = model->itemFromIndex(modelIndex);
        // 获取当前item深度
        int depth = getItemDepth(item);
        QPersistentModelIndex persistentIndex(modelIndex);
        copyDirInfo = CopyDirInfo{depth, item, persistentIndex}; 
    }

    void CenterWidget::pyDoPrjTreePasteDir(int srcId, int destId)
    {
        slot_pasteDirectoryItemData(srcId, destId);
    }

    void CenterWidget::pyDoPrjTreeCopyData(int index)
    {
        auto model = (QStandardItemModel*)ui->treeView->model();
        QModelIndex modelIndex = model->index(index, 0, QModelIndex());
        QStandardItem* item = model->itemFromIndex(modelIndex);
        int depth = getItemDepth(item);
        copyFileInfo = CopyFileInfo{depth, item};
    }

    void CenterWidget::pyDoPrjTreePasteData(int srcId, int destId)
    {
        slot_pasteFileItemData(srcId, destId);
    }

    void CenterWidget::pyDoPrjTreeExpandDir(int index)
    {
        //if (m_treeItemMap.isEmpty() || m_needFlushItemMap)
        //{
        //    traverseTreeView(QModelIndex(), 0);
        //    m_needFlushItemMap = false;
        //}
        traverseTreeView(QModelIndex(), 0);
        QStandardItem* item = m_treeItemMap[index];
        if (item == nullptr)
            return;
        ui->treeView->blockSignals(true);
        ui->treeView->expand(item->index());
        ui->treeView->setCurrentIndex(item->index());
        ui->treeView->blockSignals(false);
    }

    void CenterWidget::pyDoPrjTreeCollapseDir(int index)
    {
        //if (m_treeItemMap.isEmpty() || m_needFlushItemMap)
        //{
        //    traverseTreeView(QModelIndex(), 0);
        //    m_needFlushItemMap = false;
        //}
        traverseTreeView(QModelIndex(), 0);
        QStandardItem* item = m_treeItemMap[index];
        ui->treeView->blockSignals(true);
        ui->treeView->collapse(item->index());
        ui->treeView->setCurrentIndex(item->index());
        ui->treeView->blockSignals(false);
    }

    void CenterWidget::showContextMenu(const QPoint& pos)
    {
        emit IWidgetSignalInstance->signal_exitAddMarkerState();
        QModelIndex index = ui->treeView->indexAt(pos);
        // 检查是否点击在有效的行上
        if (!index.isValid())
        {
            return; // 如果没有有效索引，则不显示菜单
        }

        auto model = (QStandardItemModel*)ui->treeView->model();
        QStandardItem* item = model->itemFromIndex(index);

        if (item == nullptr)
        {
            return;
        }

        /*
         * 检查是不是来自导入
         */
        bool isImportData = false; 
        auto _importItemDataList = ProjectTreeDataInstance->getImportItemDataList();
        if (!item->data(Qt::UserRole + 10).isNull())
        {
            auto _itemID = item->data(Qt::UserRole + 10).toInt();
            for (const auto& pair : _importItemDataList)
            {
                if (pair.first == _itemID)
                {
                    isImportData = true;
                }
            }
        }

        // 获取上下文菜单的位置
        QMenu contextMenu(this);
        // 获取当前item深度
        int depth = getItemDepth(item);
        if (item->hasChildren())
            addFoldingAction(contextMenu, item);

        if (isImportData) // 是导入数据
        {
            QAction* closeAction = contextMenu.addAction("关闭");
            connect(closeAction, &QAction::triggered, this, [=]()
                {
                    QList<QStandardItem*> leafs = getLeafsByItem(item);
                    emit IWidgetSignalInstance->signal_closeTree(leafs);
                    if (!item->data(Qt::UserRole + 10).isNull())
                    {
                        auto _removeItemID = item->data(Qt::UserRole + 10).toInt();
                        ProjectTreeDataInstance->removePasteAndImportItemData(_removeItemID);
                    }
                    model->removeRow(item->row());

                    QStringList _pyCodes{};
                    int _index = index.row();
                    _pyCodes += QString("appPrj = PostProcessing.AppPrj()");
                    _pyCodes += QString("appPrj.doPrjCloseTree(%1)").arg(_index);
                    emit IBaseSignalInstance->signal_execPYCode(_pyCodes, true, false);

                });
        }

        if (item->parent() == nullptr && !isImportData) // 是根节点
        {
            QAction* closeAction = contextMenu.addAction("关闭");
            connect(closeAction, &QAction::triggered, this, [=]()
                { 
                    QList<QStandardItem*> leafs = getLeafsByItem(item);
                    emit IWidgetSignalInstance->signal_closeTree(leafs);
                    if (!item->data(Qt::UserRole + 10).isNull())
                    {
                        auto _removeItemID = item->data(Qt::UserRole + 10).toInt();
                        ProjectTreeDataInstance->removePasteAndImportItemData(_removeItemID);
                    }
                    model->removeRow(item->row());
                    QStringList _pyCodes{};
                    int _index = index.row();
                    _pyCodes += QString("appPrj = PostProcessing.AppPrj()");
                    _pyCodes += QString("appPrj.doPrjCloseTree(%1)").arg(_index);
                    emit IBaseSignalInstance->signal_execPYCode(_pyCodes, true, false);
                });
        }
        else if (!item->hasChildren() || isImportData) // 是叶子节点
        {
            // 创建“添加到当前图”选项
            QAction* addGraphAction = contextMenu.addAction("添加至当前图");
            connect(addGraphAction, &QAction::triggered, this, &CenterWidget::addToCurrentGraph);
            addGraphAction->setEnabled(false);

            //  添加到当前图：只允许二维折线、极坐标、三维云图、三维曲面图
            auto currentGraph = this->getCurrentGraphWindow();           
            if (qobject_cast<LineChartWindow*>(currentGraph) != nullptr)
            {
                addGraphAction->setEnabled(true);
            }
            else if (qobject_cast<PolarCoordinateGraphWindow*>(currentGraph) != nullptr)
            {
                addGraphAction->setEnabled(true);
            }
            else if (qobject_cast<ThreeDCloudMapWindow*>(currentGraph) != nullptr)
            {
                addGraphAction->setEnabled(true);
            }
            else if (qobject_cast<ThreeDSurfacePlotWindow*>(currentGraph) != nullptr)
            {
                addGraphAction->setEnabled(true);
            }

            QAction* createNewGraphAction = contextMenu.addAction("新增显示窗口");
            QMenu* subMenu = new QMenu(&contextMenu); // 二级子菜单

            if (m_is2D)
            {
                QAction* addAction = subMenu->addAction("二维折线图");
                connect(addAction, &QAction::triggered, this, [this]()
                        { emit signal_displayNew2DGraph(FileDataType::File2DCurve,true); });
            }
            if (m_isPolar)
            {
                QAction* addAction = subMenu->addAction("极坐标图");
                connect(addAction, &QAction::triggered, this, [this]()
                        { emit signal_displayNew2DGraph(FileDataType::FilePolar, true); });
            }
            if (m_isSurfaceElectricField)
            {
                QAction* addAction = subMenu->addAction("表面分布图");
                connect(addAction, &QAction::triggered, this, [this]()
                        { emit signal_displayNewSurfaceElectricFieldGraph(true); });
            }
            if (m_isTwoDHeatMap)
            {
                QAction* addAction = subMenu->addAction("二维热力图");
                connect(addAction, &QAction::triggered, this, [this]()
                        { emit signal_displayNew2DGraph(FileDataType::FileTwoDHeatMap, true); });
            }
            if (m_isThreeDCloudMap)
            {
                QAction* addAction = subMenu->addAction("三维云图");
                connect(addAction, &QAction::triggered, this, [this]()
                        { emit signal_displayNewThreeDCloudMap(true); });
            }
            if (m_isThreeDSurfacePlot)
            {
                QAction* addAction = subMenu->addAction("三维曲面图");
                connect(addAction, &QAction::triggered, this, [this]()
                        { emit signal_displayNewThreeDSurfacePlot(true); });
            }
            if (m_TwoDPeakValleyGraph)
            {
                QAction* addAction = subMenu->addAction("二维峰谷图");
                // connect(addAction, &QAction::triggered, this, [this]()
                //         { emit signal_displayNew2DGraph(); });
            }
            if (m_isDataTable)
            {
                QAction* addAction = subMenu->addAction("数据表格");
                connect(addAction, &QAction::triggered, this, [this]()
                        { emit signal_displayInTableWidget(); });
            }
            createNewGraphAction->setMenu(subMenu);

            /*
             * @description 复制文件
             */
            if (!isImportData)
            {
            QAction* copyAction = contextMenu.addAction("复制数据");
            connect(copyAction, &QAction::triggered, this, [item, this]()
            { 
                // 获取当前item深度
                int depth = getItemDepth(item);
                copyFileInfo = CopyFileInfo{depth, item}; });
                QStringList _pyCodes{};
                int _index = item->index().row();
                _pyCodes += QString("appPrj = PostProcessing.AppPrj()");
                _pyCodes += QString("appPrj.doPrjTreeCopyData(%1)").arg(_index);
                emit IBaseSignalInstance->signal_execPYCode(_pyCodes, true, false);
            }
        }
        /*
         * @description 粘贴文件:如果有复制信息，并且复制信息来源的深度减1等于当前深度，就允许粘贴
         */
        else if (copyFileInfo.has_value() && (copyFileInfo->depth - 1 == depth))
        {
            //addFoldingAction(contextMenu, item);
            QAction* pasteAction = contextMenu.addAction("粘贴数据");
            connect(pasteAction, &QAction::triggered, this, [item, this]()
                    { 
                        QStandardItem * copyFileItem=copyFileInfo->item;
                        if(!copyFileItem->data(Qt::UserRole + 10).isNull() && !item->data(Qt::UserRole + 10).isNull())
                        {
                            auto _copyItemID = copyFileItem->data(Qt::UserRole + 10).toInt();
                            auto _targetItemID = item->data(Qt::UserRole + 10).toInt();
                            slot_pasteFileItemData(_copyItemID, _targetItemID);
                            QStringList _pyCodes{};
                            _pyCodes += QString("appPrj = PostProcessing.AppPrj()");
                            _pyCodes += QString("appPrj.doPrjTreePasteData(%1, %2)").arg(_copyItemID).arg(_targetItemID);
                            emit IBaseSignalInstance->signal_execPYCode(_pyCodes, true, false);
                        } });
        }
        /*else
        {
            addFoldingAction(contextMenu, item);
        }*/

        /*
         * @description 复制目录
         */
        if (item->hasChildren() && item->parent() != nullptr)
        {
            QAction* copyAction = contextMenu.addAction("复制");
            connect(copyAction, &QAction::triggered, this, [item, model, this]()
            { 
                // 获取当前item深度
                int depth = getItemDepth(item);
                QModelIndex index = model->indexFromItem(item);
                QPersistentModelIndex persistentIndex(index);
                copyDirInfo = CopyDirInfo{depth, item, persistentIndex}; 
                
                QStringList _pyCodes{};
                int _index = index.row();
                _pyCodes += QString("appPrj = PostProcessing.AppPrj()");
                _pyCodes += QString("appPrj.doPrjTreeCopyDir(%1)").arg(_index);
                emit IBaseSignalInstance->signal_execPYCode(_pyCodes, true, false);
            });

        }
        /*
         * @description 粘贴目录:如果有复制信息，并且复制信息来源的深度减1等于当前深度，就允许粘贴
         */
        if (copyDirInfo.has_value() && (copyDirInfo->depth - 1 == depth) && copyDirInfo->persistentIndex.isValid())
        {
            //addFoldingAction(contextMenu, item);
            QAction* pasteAction = contextMenu.addAction("粘贴", this, [item, this]()
                { 
                    QStandardItem * copyDirItem = copyDirInfo->item;
                    if(!copyDirItem->data(Qt::UserRole + 10).isNull() && !item->data(Qt::UserRole + 10).isNull())
                    {
                        auto _copyItemID = copyDirItem->data(Qt::UserRole + 10).toInt();
                        auto _targetItemID = item->data(Qt::UserRole + 10).toInt();
                        slot_pasteDirectoryItemData(_copyItemID, _targetItemID);

                        QStringList _pyCodes{};
                        _pyCodes += QString("appPrj = PostProcessing.AppPrj()");
                        _pyCodes += QString("appPrj.doPrjTreePasteDir(%1, %2)").arg(_copyItemID).arg(_targetItemID);
                        emit IBaseSignalInstance->signal_execPYCode(_pyCodes, true, false);

                    } 
                });
        }

        contextMenu.exec(ui->treeView->viewport()->mapToGlobal(pos));
    }

    void CenterWidget::addFoldingAction(QMenu& contextMenu, QStandardItem* item)
    {
        auto _isExpanded = ui->treeView->isExpanded(item->index());
        //auto itemId = item->data(Qt::UserRole + 10).toInt();

        if (!_isExpanded)
        {
            QAction* _unFoldingAction = contextMenu.addAction("展开");
            connect(_unFoldingAction, &QAction::triggered, this, [=]()
            { 
                ui->treeView->expand(item->index()); 
                //saveCollapseOrExpandPyCode(true, itemId);
            });
        }
        else
        {
            QAction* _foldingAction = contextMenu.addAction("折叠");
            connect(_foldingAction, &QAction::triggered, this, [=]()
            {
                ui->treeView->collapse(item->index()); 
                //saveCollapseOrExpandPyCode(false, itemId);
            });
        }
    }

    HeatMapWindow* CenterWidget::getHeatMapWindowByWindowID(int windowID)
    {
        for (auto windowPair : m_heatMapWindowList)
        {
            if (windowPair.first == windowID)
            {
                return windowPair.second;
            }
        }
        return nullptr;
    }
    PolarCoordinateGraphWindow* CenterWidget::getPolarCoordinateGraphWindowByWindowID(int windowID)
    {
        for (auto windowPair : m_polarCoordinateGraphWindowList)
        {
            if (windowPair.first == windowID)
            {
                return windowPair.second;
            }
        }
        return nullptr;

    }
    LineChartWindow* CenterWidget::getLineChartWindowByWindowID(int windowID)
    {
        for (auto windowPair : m_lineChartWindowList)
        {
            if (windowPair.first == windowID)
            {
                return windowPair.second;
            }
        }
        return nullptr;

    }
    ThreeDSurfacePlotWindow* CenterWidget::getThreeDSurfacePlotWindowByWindowID(int windowID)
    {
        for (auto windowPair : m_surfacePlotWindowList)
        {
            if (windowPair.first == windowID)
            {
                return windowPair.second;
            }
        }
        return nullptr;

    }
    ThreeDCloudMapWindow* CenterWidget::getThreeDCloudMapWindowByWindowID(int windowID)
    {
        for (auto windowPair : m_threeDCloudMapWindowList)
        {
            if (windowPair.first == windowID)
            {
                return windowPair.second;
            }
        }
        return nullptr;

    }
    SurfaceElectricFieldMapWindow* CenterWidget::getSurfaceElectricFieldMapWindowByWindowID(int windowID)
    {
        for (auto windowPair : m_surfaceElectricFieldMapWindowList)
        {
            if (windowPair.first == windowID)
            {
                return windowPair.second;
            }
        }
        return nullptr;
    }

    void CenterWidget::clearData()
    {
        
        for (auto _2Dwindow : m_graph2DList)
        {
            if (_2Dwindow)
            {
                delete _2Dwindow;
                _2Dwindow = nullptr;
            }
        }
        m_graph2DList.clear();
        
        for (auto _3Dwindow : m_graph3DList)
        {
            if (_3Dwindow)
            {
                delete _3Dwindow;
                _3Dwindow = nullptr;
            }
        }
        m_graph3DList.clear();
        m_tabNameNum.clear();
        m_heatMapWindowList.clear();
        m_polarCoordinateGraphWindowList.clear();
        m_lineChartWindowList.clear();
        m_surfacePlotWindowList.clear();
        m_threeDCloudMapWindowList.clear();
        m_surfaceElectricFieldMapWindowList.clear();
        m_tableWindowList.clear();
    }

    void CenterWidget::addToCurrentGraph()
    {
        emit signal_addToCurrentGraph(getSelectedItems());
    }

    void CenterWidget::addFileNode(QStandardItem* item, bool isImprotData)
    {
        auto model = (QStandardItemModel*)ui->treeView->model();
        // model->item(0)->appendRow(item);
        model->appendRow(item);
        if (isImprotData)
        {
            auto _index = model->indexFromItem(item);
            ui->treeView->setCurrentIndex(_index);
            auto indexs = getSelectedItems();
            emit signal_fileClicked(indexs);
        }
        m_needFlushItemMap = true;
    }

    void CenterWidget::setTreeViewState(bool isEnabled)
    {
        ui->treeView->setEnabled(isEnabled);
    }

    QList<QStandardItem*> CenterWidget::getSelectedItems()
    {
        QList<QStandardItem*> selectedItems;
        QModelIndexList indexes = ui->treeView->selectionModel()->selectedIndexes();
        for (const QModelIndex& index : indexes)
        {
            auto model = (QStandardItemModel*)ui->treeView->model();
            selectedItems.append(model->itemFromIndex(index));
        }
        return selectedItems;
    }

    AnimationSettingData* CenterWidget::getAnimationSettingData() const
    {
        return m_animationSettingData;
    }

    // void CenterWidget::slot_fileClicked(const QModelIndex& index)
    //{
    //     emit
    // }
    // void CenterWidget::addNewProject()
    //{
    // }

    void CenterWidget::addLineToGrapg2D(Graph2DWindowBase* _graph2D,
                                        const QPair<QString, QVector<double>>& x,
                                        const QPair<QString, QVector<double>>& y)
    {
        //_graph2D->addLine(x, y);
    }

    void CenterWidget::addImageToGrapg2D(Info2DPointer& info)
    {
        if (info->getGraph() == nullptr)
        {
            return;
        }
        info->getGraph()->addGraph2D(info);
        //if (qobject_cast<HeatMapWindow*>(info->getGraph()) != nullptr)
        //{
        //    qobject_cast<HeatMapWindow*>(info->getGraph())->setAnimationSettingData(m_animationSettingData);
        //}

        // info.setCurveLineAddress(curAddress);
    }

    void CenterWidget::addImageToNewGrapg2DWindow(QList<Info2DPointer>& infos, bool useNewWindow)
    {
        Graph2DWindowBase* graph{nullptr};
        if (useNewWindow)
        {
            if (!infos.isEmpty())
            {
                const auto& info = infos.first();
                if (info->getGraphType() == GraphType::TwoDHeatMap)
                {
                    const auto& column1 = info->getReader()->getEachColDataOfKey().at(info->getReader()->getScanParameterIndex());
                    const auto& column2 = info->getReader()->getEachColDataOfKey().at(info->getReader()->getSecondScanParameterIndex());
                    const auto& minMax1 = std::minmax_element(column1.begin(), column1.end());
                    const auto& minMax2 = std::minmax_element(column2.begin(), column2.end());
                    if (std::abs(minMax1.second - minMax1.first) <= std::numeric_limits<double>::epsilon() || std::abs(minMax2.second - minMax2.first) <= std::numeric_limits<double>::epsilon())
                    {
                        emit IBaseSignalInstance->signal_sendErrorMessageToUI("选择变量数据不满足绘制二维热力图条件");
                        return;
                    }
                }
                graph = addNewGraph2D(infos.first()->getGraphType());
            }
        }
        else
        {
            graph = qobject_cast<Graph2DWindowBase*>(ui->tabWidget->currentWidget());
        }
        if (graph == nullptr)
        {
            emit IBaseSignalInstance->signal_sendErrorMessageToUI("图像类型不匹配");
            return;
        }

        const auto& curveMap = graph->getCurve();
        if (!curveMap.isEmpty())
        {
            const auto& value = curveMap.at(0).second;
            //const auto& value = curveMap.begin().value();
            const auto& str = value->getReader()->getEachColNameOfKey().at(value->getScanParameterIndex());
            for (auto i : infos)
            {
                if (str.toLower() != i->getReader()->getEachColNameOfKey().at(i->getScanParameterIndex()).toLower())
                {
                    emit IBaseSignalInstance->signal_sendErrorMessageToUI("数据变量不一致，请重新选择工程文件");
                    return;
                }
            }
        }
        m_isCanCloseTab = false;
        for (auto i : infos)
        {
            i->setGraph(graph);
            addImageToGrapg2D(i);
        }
        m_isCanCloseTab = true;
        if (m_isActiveAuto)
        {
            ui->tabWidget->setCurrentWidget(graph);
        }
    }

    void CenterWidget::slot_pasteFileItemData(int srcItemID, int TargetItemID)
    {
        auto _srcItem = ProjectTreeDataInstance->getProjectTreeItemByID(srcItemID);
        auto _targetItem = ProjectTreeDataInstance->getProjectTreeItemByID(TargetItemID);
        // 粘贴节点
        QString label = _srcItem->text();
        QStandardItem* pasteFileItem = new QStandardItem(label);
        pasteFileItem->setData(ProjectTreeDataInstance->generateProjectTreeItemID(), Qt::UserRole + 10);
        //获取修饰后的名称
        QString text = getPasteItemText(_srcItem, _targetItem);
        pasteFileItem->setText(text);
        _targetItem->appendRow(pasteFileItem);
        ProjectTreeDataInstance->appendPasteAndImportItemData(_srcItem->data(Qt::UserRole + 10).toInt(), _targetItem->data(Qt::UserRole + 10).toInt(), QString(""));
        // 粘贴数据信号
        emit signal_pasteFile(_srcItem, pasteFileItem);

    }
    void CenterWidget::slot_pasteDirectoryItemData(int srcItemID, int TargetItemID)
    {
        auto _srcItem = ProjectTreeDataInstance->getProjectTreeItemByID(srcItemID);
        auto _targetItem = ProjectTreeDataInstance->getProjectTreeItemByID(TargetItemID);
        QStandardItem* pasteFileItem = deepCopyItem(_srcItem, [this](QStandardItem* newItem, const QStandardItem* source)
                                                    {
                        if(!source->hasChildren())
                        {
                            emit signal_pasteFile(const_cast<QStandardItem*>(source), newItem);
                        } });
        //pasteFileItem->
        // 获取修饰后的名称
        QString text = getPasteItemText(_srcItem, _targetItem);
        pasteFileItem->setText(text);
        _targetItem->appendRow(pasteFileItem);

        ProjectTreeDataInstance->appendPasteAndImportItemData(_srcItem->data(Qt::UserRole + 10).toInt(), _targetItem->data(Qt::UserRole + 10).toInt(), QString(""));
        auto _data = pasteFileItem->data(Qt::UserRole + 10).toInt();
    }

    void CenterWidget::slot_projectTreeSelectionChanged(QList<int> projectTreeSelctedRowIDList, bool* isSuccess)
    {
        auto model = (QStandardItemModel*)ui->treeView->model();
        QList<QStandardItem*> selectedItems;
        for (auto _rowID : projectTreeSelctedRowIDList)
        {
            auto _item = ProjectTreeDataInstance->getProjectTreeItemByID(_rowID);
            if (_item != nullptr)
            {
                selectedItems.append(_item);
                auto _itemindex = model->indexFromItem(_item);
                ui->treeView->setCurrentIndex(_itemindex);
            }
        }
        emit signal_fileClicked(selectedItems); 
        *isSuccess = true;
    }

    void CenterWidget::slot_addImageToNewGrapg2DWindow(QList<Info2DPointer>& infos)
    {
        addImageToNewGrapg2DWindow(infos, true);
    }

    void CenterWidget::slot_saveScreenShot(const QString& path, bool* isSuccess)
    {
        bool _isSuccess = false;
        // return _graph2D->saveScreenShot(path);
        QWidget* currentGraph = ui->tabWidget->currentWidget();
        if (qobject_cast<Graph2DWindowBase*>(currentGraph) != nullptr)
        {
            _isSuccess = qobject_cast<Graph2DWindowBase*>(currentGraph)->saveScreenShot(path);
        }
        else if (qobject_cast<Graph3DWindowBase*>(currentGraph) != nullptr)
        {
            _isSuccess = qobject_cast<Graph3DWindowBase*>(currentGraph)->saveScreenShot(path);
        }

        *isSuccess = _isSuccess;
    }

    void CenterWidget::slot_setHeatMapSelectedCurveNameIndexs(int windowId, QList<int> selectedCurveNameIndexs)
    {
        HeatMapWindow* graph = getHeatMapWindowByWindowID(windowId);
        if (graph != nullptr)
        {
            graph->setSelectedCurveNameIndexs(selectedCurveNameIndexs);
        }
    }

    void CenterWidget::slot_setHeatMapVariableAxisChanged(int windowId, int variableAxisIndex)
    {
        HeatMapWindow* graph = getHeatMapWindowByWindowID(windowId);
        if (graph != nullptr)
        {
            graph->setVariableAxisChanged(variableAxisIndex);
        }
    }

    void CenterWidget::slot_setHeatMapFixedValueChanged(int windowId, QList<int> indexList)
    {
        HeatMapWindow* graph = getHeatMapWindowByWindowID(windowId);
        if (graph != nullptr)
        {
            graph->setFixedValueChanged(indexList);
        }
    }

    void CenterWidget::slot_setHeatMapComplexPartsChanged(int windowId, bool isAmplitudeChecked, bool isPhaseChecked, bool isRealPartChecked, bool isImaginaryPartChecked)
    {
        HeatMapWindow* graph = getHeatMapWindowByWindowID(windowId);
        if (graph != nullptr)
        {
            graph->setComplexPartsChanged(isAmplitudeChecked, isPhaseChecked, isRealPartChecked, isImaginaryPartChecked);
        }
    }

    void CenterWidget::slot_setHeatMapSecondVariableAxisChanged(int windowId, int variableAxisIndex)
    {
        HeatMapWindow* graph = getHeatMapWindowByWindowID(windowId);
        if (graph != nullptr)
        {
            graph->setSecondVariableAxisChanged(variableAxisIndex);
        }
    }

    void CenterWidget::slot_setHeatMapCurveNameCheckStateChanged(int windowId, int curveNameIndex, bool checkState)
    {
        HeatMapWindow* graph = getHeatMapWindowByWindowID(windowId);
        if (graph != nullptr)
        {
            graph->setCurveNameCheckStateChanged(curveNameIndex, checkState);
        }
    }

    void CenterWidget::slot_setHeatMapDataOprationChanged(int windowId, bool isLoged, bool isNormalized)
    {
        HeatMapWindow* graph = getHeatMapWindowByWindowID(windowId);
        if (graph != nullptr)
        {
            graph->setDataOprationChanged(isLoged, isNormalized);
        }
    }

    void CenterWidget::slot_setHeatMapResultValueDataChanged(int windowId, int index)
    {
        HeatMapWindow* graph = getHeatMapWindowByWindowID(windowId);
        if (graph != nullptr)
        {
            graph->setResultValueDataChanged(index);
        }
    }

    void CenterWidget::slot_saveHeatMapMainSettingData(int windowId, bool scalarBarIsAutoRange,
                                                       double scalarBarMin, double scalarBarMax, QString scalarBarColor, int scalarBarFontSize,
                                                       bool XAxisAutoTitle, QString XAxisTitle, QString XTitleFontColor, int XTitleFontSize, QString XAxisColor,
                                                       double XAisThickness, int XValuePrecision, QString XAxisDigitColor, int XAxisDigitSize,
                                                       bool XAxisIsAutoRange, double XAxisMax, double XAxisMin, bool XIsAutoStepSize,
                                                       double XCustomStepSize, bool YAxisAutoTitle, QString YAxisTitle, QString YTitleFontColor, int YTitleFontSize,
                                                       QString YAxisColor, double YAisThickness, int YValuePrecision, QString YAxisDigitColor,
                                                       int YAxisDigitSize, bool YAxisIsAutoRange, double YAxisMax, double YAxisMin,
                                                       bool YIsAutoStepSize, double YCustomStepSize, bool gridIsMainGridLineDisplay,
                                                       QString gridMainGridLineColor, int gridMainGridLineStyle, double gridMainGridLineThickness,
                                                       bool gridIsSecondaryGridLineDisplay, QString gridSecondaryGridLineColor,
                                                       int gridSecondaryGridLineStyle, double gridSecondaryGridLineThickness,
                                                       QString windowTitleName, QString windowTitleFontColor, int windowTitleFontSize)
    {
        HeatMapWindow* graph = getHeatMapWindowByWindowID(windowId);
        if (graph != nullptr)
        {
            graph->saveHeatMapMainSettingData(scalarBarIsAutoRange, scalarBarMin,
                                              scalarBarMax, scalarBarColor, scalarBarFontSize, XAxisAutoTitle, XAxisTitle,
                                              XTitleFontColor, XTitleFontSize, XAxisColor, XAisThickness,
                                              XValuePrecision, XAxisDigitColor, XAxisDigitSize, XAxisIsAutoRange,
                                              XAxisMax, XAxisMin, XIsAutoStepSize, XCustomStepSize, YAxisAutoTitle, YAxisTitle,
                                              YTitleFontColor, YTitleFontSize, YAxisColor, YAisThickness,
                                              YValuePrecision, YAxisDigitColor, YAxisDigitSize, YAxisIsAutoRange,
                                              YAxisMax, YAxisMin, YIsAutoStepSize, YCustomStepSize,
                                              gridIsMainGridLineDisplay, gridMainGridLineColor, gridMainGridLineStyle,
                                              gridMainGridLineThickness, gridIsSecondaryGridLineDisplay, gridSecondaryGridLineColor,
                                              gridSecondaryGridLineStyle, gridSecondaryGridLineThickness,
                                              windowTitleName, windowTitleFontColor, windowTitleFontSize);
        }
    }

    void CenterWidget::slot_setHeatMapRemoveSelectedGraph(int windowId)
    {
        HeatMapWindow* graph = getHeatMapWindowByWindowID(windowId);
        if (graph != nullptr)
        {
            graph->setRemoveSelectedGraph();
        }
    }

    void CenterWidget::slot_setHeatMapRenameFinished(int windowId, QString name)
    {
        HeatMapWindow* graph = getHeatMapWindowByWindowID(windowId);
        if (graph != nullptr)
        {
            graph->setRenameFinished(name);
        }
    }

    void CenterWidget::slot_setHeatMapAddTracer(int windowId, QString name, double x, double y, double value, int tracerStyle, int size, int penR, int penG, int penB, int penA, int interpolating, int curveInfoID, int tracerIndex)
    {
        HeatMapWindow* graph = getHeatMapWindowByWindowID(windowId);
        if (graph != nullptr)
        {
            graph->pyAddTracer(name, x, y, value, tracerStyle, size, penR, penG, penB, penA, interpolating, curveInfoID, tracerIndex);
        }
    }

    void CenterWidget::slot_setHeatMapRemoveSelectedTracer(int windowId, QList<int> infoIdList)
    {
        HeatMapWindow* graph = getHeatMapWindowByWindowID(windowId);
        if (graph != nullptr)
        {
            graph->pyRemoveSelectedTracer(infoIdList);
        }
    }

    void CenterWidget::slot_setHeatMapRemoveAllTracer(int windowId, QList<int> infoIdList)
    {
        HeatMapWindow* graph = getHeatMapWindowByWindowID(windowId);
        if (graph != nullptr)
        {
            graph->pyRemoveAllTracer(infoIdList);
        }
    }

    void CenterWidget::slot_setHeatMapExportMarkerData(int windowId, QString fileName)
    {
        HeatMapWindow* graph = getHeatMapWindowByWindowID(windowId);
        if (graph != nullptr)
        {
            graph->pyExportMarkerData(fileName);
        }
    }

    void CenterWidget::slot_setHeatMapChangeTracerProperty(int windowId, QString name, int symbolStyle, int size, int penR, int penG, int penB, int penA, int tracerID)
    {
        HeatMapWindow* graph = getHeatMapWindowByWindowID(windowId);
        if (graph != nullptr)
        {
            graph->pyChangeTracerProperty(name, symbolStyle, size, penR, penG, penB, penA, tracerID);
        }
    }

    void CenterWidget::slot_lineChartSidebarVariableAxisChanged(int mainWindowId, QList<int> allSelectedItem, int reuslt, QString sVariableAxistCurrentText)
    {
        LineChartWindow* graph = getLineChartWindowByWindowID(mainWindowId);
        if (graph != nullptr)
        {
            graph->pyVariableAxisChanged(allSelectedItem, reuslt, sVariableAxistCurrentText);
        }
    }

    void CenterWidget::slot_lineChartSidebarCurveNameClicked(int mainWindowId, QList<int> allSelectedItemIndexList)
    {
        LineChartWindow* graph = getLineChartWindowByWindowID(mainWindowId);
        if (graph != nullptr)
        {
            graph->pyCurveNameClicked(allSelectedItemIndexList);
        }
    }

    void CenterWidget::slot_lineChartSidebarCurveNameCheckStateChanged(int mainWindowId, int index, int checkStatus)
    {
        LineChartWindow* graph = getLineChartWindowByWindowID(mainWindowId);
        if (graph != nullptr)
        {
            graph->pyCurveNameCheckStateChanged(index, checkStatus);
        }
    }

    void CenterWidget::slot_lineChartSidebarFixedValueChanged(int mainWindowId, QList<int> allIndexLis)
    {
        LineChartWindow* graph = getLineChartWindowByWindowID(mainWindowId);
        if (graph != nullptr)
        {
            graph->pyFixedValueChanged(allIndexLis);
        }
    }

    void CenterWidget::slot_lineChartSidebarDataOperationChanged(int mainWindowId, bool isNormChecked, bool isDBChecked, bool isMathOperationChecked)
    {
        LineChartWindow* graph = getLineChartWindowByWindowID(mainWindowId);
        if (graph != nullptr)
        {
            graph->pyDataOperationChanged(isNormChecked, isDBChecked, isMathOperationChecked);
        }
    }

    void CenterWidget::slot_lineChartSidebarValueDataChanged(int mainWindowId, int currentIndex)
    {
        LineChartWindow* graph = getLineChartWindowByWindowID(mainWindowId);
        if (graph != nullptr)
        {
            graph->pyDataOperationChanged(currentIndex);
        }
    }

    void CenterWidget::slot_lineChartSaveMainSettingData(int mainWindowId, int index,
                                                         bool axiDisIsAutoName, QString axiDisTitleText, QString axiDisTitleFontColorStr, int axiDisTitleFontSize, QString axiDisAxisColorStr, int axiDisAxisThickness, double axiDisValuePrecision, QString axiDisAxisDigitColorStr, int axiDisAxisDigitSize,
                                                         bool axiRangIsAutoRange, double axiRangMaxValue, double axiRangMinValue, bool axiRangIsAutoStepSize, double axiRangCustomStepSize,
                                                         bool yAxiDisIsAutoName, QString yAxiDisTitleText, QString yAxiDisTitleFontColorStr, int yAxiDisTitleFontSize, QString yAxiDisAxisColorStr, int yAxiDisAxisThickness, double yAxiDisValuePrecision, QString yAxiDisAxisDigitColorStr, int yAxiDisAxisDigitSize,
                                                         bool yAxiRangIsAutoRange, double yAxiRangMaxValue, double yAxiRangMinValue, bool yAxiRangIsAutoStepSize, double yAxiRangCustomStepSize,
                                                         bool gridIsMainGridLineDisplay, QString gridMainGridLineColorStr, int gridMainGridLineStyle, double gridMainGridLineThickness, bool gridIsSecondaryGridLineDisplay, QString gridSecondaryGridLineColorStr, int gridSecondaryGridLineStyle, double gridSecondaryGridLineThickness,
                                                         QString titleName, QString titleFontColorStr, int titleFontSize,
                                                         QString legendFontColorStr, int legendFontSize, QString legendLineColorStr, int legendLineThickness,
                                                         QString resultDataName, QString dataLineColorStr, int dataLineStyle, double dataLineThickness, bool isDisplaySymbol, int symbolStyle, double symbolSize, QString symbolColorStr)
    {
        LineChartWindow* graph = getLineChartWindowByWindowID(mainWindowId);
        if (graph != nullptr)
        {
            graph->slot_lineChartSaveMainSettingData(index,
                                                     axiDisIsAutoName, axiDisTitleText, axiDisTitleFontColorStr, axiDisTitleFontSize, axiDisAxisColorStr, axiDisAxisThickness, axiDisValuePrecision, axiDisAxisDigitColorStr, axiDisAxisDigitSize,
                                                     axiRangIsAutoRange, axiRangMaxValue, axiRangMinValue, axiRangIsAutoStepSize, axiRangCustomStepSize,
                                                     yAxiDisIsAutoName, yAxiDisTitleText, yAxiDisTitleFontColorStr, yAxiDisTitleFontSize, yAxiDisAxisColorStr, yAxiDisAxisThickness, yAxiDisValuePrecision, yAxiDisAxisDigitColorStr, yAxiDisAxisDigitSize,
                                                     yAxiRangIsAutoRange, yAxiRangMaxValue, yAxiRangMinValue, yAxiRangIsAutoStepSize, yAxiRangCustomStepSize,
                                                     gridIsMainGridLineDisplay, gridMainGridLineColorStr, gridMainGridLineStyle, gridMainGridLineThickness, gridIsSecondaryGridLineDisplay, gridSecondaryGridLineColorStr, gridSecondaryGridLineStyle, gridSecondaryGridLineThickness,
                                                     titleName, titleFontColorStr, titleFontSize,
                                                     legendFontColorStr, legendFontSize, legendLineColorStr, legendLineThickness,
                                                     resultDataName, dataLineColorStr, dataLineStyle, dataLineThickness, isDisplaySymbol, symbolStyle, symbolSize, symbolColorStr);
        }
    }
    

    void CenterWidget::slot_lineChartWindowAddTracer(int windowUniversalID, QString parameters)
    {
        auto windowBase = WindowTotalDataInstance->getGraph2DWindowByUniversalID(windowUniversalID);
        if(qobject_cast<LineChartWindow*>(windowBase) != nullptr)
        {
            auto lineChartWindow = qobject_cast<LineChartWindow*>(windowBase);
            lineChartWindow->pyAddTracer(parameters);
        }
    }

    void CenterWidget::slot_polarCoordinateGraphSidebarVariableAxisChanged(int mainWindowId, QList<int> allSelectedItem, int reuslt, QString sVariableAxistCurrentText)
    {
        PolarCoordinateGraphWindow* graph = getPolarCoordinateGraphWindowByWindowID(mainWindowId);
        if (graph != nullptr)
        {
            graph->pyVariableAxisChanged(allSelectedItem, reuslt, sVariableAxistCurrentText);
        }
    }

    void CenterWidget::slot_polarCoordinateGraphSidebarAllVariableAxisChanged(int mainWindowId, QString sVariableAxistCurrentText)
    {
        PolarCoordinateGraphWindow* graph = getPolarCoordinateGraphWindowByWindowID(mainWindowId);
        if (graph != nullptr)
        {
            graph->pyAllVariableAxisChanged(sVariableAxistCurrentText);
        }
    }

    void CenterWidget::slot_polarCoordinateGraphSidebarCurveNameClicked(int mainWindowId, QList<int> allSelectedItemIndexList)
    {
        PolarCoordinateGraphWindow* graph = getPolarCoordinateGraphWindowByWindowID(mainWindowId);
        if (graph != nullptr)
        {
            graph->pyCurveNameClicked(allSelectedItemIndexList);
        }
    }

    void CenterWidget::slot_polarCoordinateGraphSidebarCurveNameCheckStateChanged(int mainWindowId, int index, int checkStatus)
    {
        PolarCoordinateGraphWindow* graph = getPolarCoordinateGraphWindowByWindowID(mainWindowId);
        if (graph != nullptr)
        {
            graph->pyCurveNameCheckStateChanged(index, checkStatus);
        }
    }

    void CenterWidget::slot_polarCoordinateGraphSidebarDataOperationChanged(int mainWindowId, bool isNormChecked, bool isDBChecked)
    {
        PolarCoordinateGraphWindow* graph = getPolarCoordinateGraphWindowByWindowID(mainWindowId);
        if (graph != nullptr)
        {
            graph->pyDataOperationChanged(isNormChecked, isDBChecked);
        }
    }

    void CenterWidget::slot_polarCoordinateGraphSidebarValueDataChanged(int mainWindowId, int currentIndex)
    {
        PolarCoordinateGraphWindow* graph = getPolarCoordinateGraphWindowByWindowID(mainWindowId);
        if (graph != nullptr)
        {
            graph->pyDataOperationChanged(currentIndex);
        }
    }

    void CenterWidget::slot_polarCoordinateGraphSidebarDeleteAllGraph(int mainWindowId)
    {
        PolarCoordinateGraphWindow* graph = getPolarCoordinateGraphWindowByWindowID(mainWindowId);
        if (graph != nullptr)
        {
            graph->pyDeleteAllGraph();
        }
    }

    void CenterWidget::slot_polarCoordinateGraphSidebarRenameSelectedGraph(int mainWindowId, QString name)
    {
        PolarCoordinateGraphWindow* graph = getPolarCoordinateGraphWindowByWindowID(mainWindowId);
        if (graph != nullptr)
        {
            graph->pyRenameSelectedGraph(name);
        }
    }

    void CenterWidget::slot_polarCoordinateGraphSidebarComplexPartsChanged(int windowId, bool isAmplitudeChecked, bool isPhaseChecked, bool isRealPartChecked, bool isImaginaryPartChecked)
    {
        PolarCoordinateGraphWindow* graph = getPolarCoordinateGraphWindowByWindowID(windowId);
        if (graph != nullptr)
        {
            graph->pyComplexPartsChanged(isAmplitudeChecked, isPhaseChecked, isRealPartChecked, isImaginaryPartChecked);
        }
    }

    void CenterWidget::slot_polarCoordinateGraphSidebarFixedValueChanged(int windowId, QList<int> indexList)
    {
        PolarCoordinateGraphWindow* graph = getPolarCoordinateGraphWindowByWindowID(windowId);
        if (graph != nullptr)
        {
            graph->pyFixedValueChanged(indexList);
        }
    }

    void CenterWidget::slot_polarCoordinateGraphSidebarRemoveSelectedGraph(int windowId, QList<int> indexList)
    {
        PolarCoordinateGraphWindow* graph = getPolarCoordinateGraphWindowByWindowID(windowId);
        if (graph != nullptr)
        {
            graph->pyRemoveSelectedGraph(indexList);
        }
    }

    void CenterWidget::slot_polarCoordinateGraphSidebarCopySelectedGraph(int windowId)
    {
        PolarCoordinateGraphWindow* graph = getPolarCoordinateGraphWindowByWindowID(windowId);
        if (graph != nullptr)
        {
            graph->pyCopySelectedGraph();
        }
    }

    void CenterWidget::slot_polarCoordinateGraphAddTracer(int windowId, QString name, double angle, int tracerStyle, int size, int penR, int penG, int penB, int penA,
                                                            int brushR, int brushG, int brushB, int brushA, int interpolating, int curveInfoID, int tracerIndex)
    {
        PolarCoordinateGraphWindow* graph = getPolarCoordinateGraphWindowByWindowID(windowId);
        if (graph != nullptr)
        {
            graph->pyAddTracer(name, angle, tracerStyle, size, penR, penG, penB, penA, brushR, brushG, brushB, brushA, interpolating, curveInfoID, tracerIndex);
        }
    }

    void CenterWidget::slot_polarCoordinateGraphRemoveSelectedTracer(int windowId, QList<int> infoIdList, int curveInfoID)
    {
        PolarCoordinateGraphWindow* graph = getPolarCoordinateGraphWindowByWindowID(windowId);
        if (graph != nullptr)
        {
            graph->pyRemoveSelectedTracer(infoIdList, curveInfoID);
        }
    }

    void CenterWidget::slot_polarCoordinateGraphRemoveAllTracer(int windowId, QList<int> infoIdList)
    {
        PolarCoordinateGraphWindow* graph = getPolarCoordinateGraphWindowByWindowID(windowId);
        if (graph != nullptr)
        {
            graph->pyRemoveAllTracer(infoIdList);
        }
    }

    void CenterWidget::slot_polarCoordinateGraphExportMarkerData(int windowId, QString fileName)
    {
        PolarCoordinateGraphWindow* graph = getPolarCoordinateGraphWindowByWindowID(windowId);
        if (graph != nullptr)
        {
            graph->pyExportMarkerData(fileName);
        }
    }

    void CenterWidget::slot_polarCoordinateGraphChangeTracerProperty(int windowId, QString name, double x, int symbolStyle, int size, int penR, int penG, int penB, int penA, int tracerID)
    {
        PolarCoordinateGraphWindow* graph = getPolarCoordinateGraphWindowByWindowID(windowId);
        if (graph != nullptr)
        {
            graph->pyChangeTracerProperty(name, x, symbolStyle, size, penR, penG, penB, penA, tracerID);
        }
    }

    void CenterWidget::slot_polarCoordinateGraphSaveMainSettingData(int mainWindowId, int index, QString angDisAxisColor, int angDisAxisThickness, double angDisValuePrecision, QString angDisAxisDigitColor, int angDisAxisDigitSize,
                                                                    bool angRangIsAutoStepSize, double angRangCustomStepSize,
                                                                    QString radDisAxisColorStr, int radDisAxisThickness, double radDisValuePrecision, QString radDisAxisDigitColorStr, int radDisAxisDigitSize,
                                                                    bool radRangIsAutoRange, double radRangMaxValue, double radRangMinValue, bool radRangIsAutoStepSize, double radRangCustomStepSize,
                                                                    bool gridIsMainGridLineDisplay, QString gridMainGridLineColor, int gridMainGridLineStyle, double gridMainGridLineThickness,
                                                                    QString titleName, QString titleFontColor, int titleFontSize,
                                                                    QString legendFontColor, int legendFontSize, QString legendLineColor, int legendLineThickness,
                                                                    QString dataProResultDataName, QString dataProDataLineColor, int dataProDataLineStyle, double dataProDataLineThickness, bool dataProIsDisplaySymbol, int dataProSymbolStyle, double dataProSymbolSize, QString dataProSymbolColor)
    {
        PolarCoordinateGraphWindow* graph = getPolarCoordinateGraphWindowByWindowID(mainWindowId);
        if (graph != nullptr)
        {
            graph->slot_polarCoordinateGraphSaveMainSettingData(mainWindowId, index, angDisAxisColor, angDisAxisThickness, angDisValuePrecision, angDisAxisDigitColor, angDisAxisDigitSize,
                                                                angRangIsAutoStepSize, angRangCustomStepSize,
                                                                radDisAxisColorStr, radDisAxisThickness, radDisValuePrecision, radDisAxisDigitColorStr, radDisAxisDigitSize,
                                                                radRangIsAutoRange, radRangMaxValue, radRangMinValue, radRangIsAutoStepSize, radRangCustomStepSize,
                                                                gridIsMainGridLineDisplay, gridMainGridLineColor, gridMainGridLineStyle, gridMainGridLineThickness,
                                                                titleName, titleFontColor, titleFontSize,
                                                                legendFontColor, legendFontSize, legendLineColor, legendLineThickness,
                                                                dataProResultDataName, dataProDataLineColor, dataProDataLineStyle, dataProDataLineThickness, dataProIsDisplaySymbol, dataProSymbolStyle, dataProSymbolSize, dataProSymbolColor);
        }
    }

    void CenterWidget::slot_threeDSurfacePlotSidebarCurveNameClicked(int windowId, QList<int> selectedIndexes)
    {
        ThreeDSurfacePlotWindow* graph = getThreeDSurfacePlotWindowByWindowID(windowId);
        if (graph != nullptr)
        {
            graph->pyCurveNameClicked(selectedIndexes);
        }
    }

    void CenterWidget::slot_threeDSurfacePlotSidebarFrequencyChanged(int windowId, int frequencyId)
    {
        ThreeDSurfacePlotWindow* graph = getThreeDSurfacePlotWindowByWindowID(windowId);
        if (graph != nullptr)
        {
            graph->pyFrequencyChanged(frequencyId);
        }
    }

    void CenterWidget::slot_threeDSurfacePlotSidebarResultDataChanged(int windowId, int resultDataIndex)
    {
        ThreeDSurfacePlotWindow* graph = getThreeDSurfacePlotWindowByWindowID(windowId);
        if (graph != nullptr)
        {
            graph->pyResultDataChanged(resultDataIndex);
        }
    }

    void CenterWidget::slot_threeDSurfacePlotSidebarDataOprationChanged(int windowId, bool isLoged, bool isNormalized)
    {
        ThreeDSurfacePlotWindow* graph = getThreeDSurfacePlotWindowByWindowID(windowId);
        if (graph != nullptr)
        {
            graph->pyDataOprationChanged(isLoged, isNormalized);
        }
    }

    void CenterWidget::slot_threeDSurfacePlotSidebarCurveNameItemCheckStateChanged(int windowId, int itemIndex, bool checkState)
    {
        ThreeDSurfacePlotWindow* graph = getThreeDSurfacePlotWindowByWindowID(windowId);
        if (graph != nullptr)
        {
            graph->pyItemCheckStateChanged(itemIndex, checkState);
        }
    }

    void CenterWidget::slot_saveThreeDSurfacePlotMainSettingData(
        int windowId, int settingDataId, bool scalarBarIsAutoRange,
        double scalarBarMin, double scalarBarMax, bool scalarBarIsShowTitle,
        QString scalarBarTitle, QString scalarBarFontColor, int scalarBarFontSize,
        int geometryTransparency, QString resultGraphName,
        int resultGraphModelTransparency, double resultGraphScale, bool cubeAxesIsVisible)
    {
        ThreeDSurfacePlotWindow* graph = getThreeDSurfacePlotWindowByWindowID(windowId);
        if (graph != nullptr)
        {
            graph->pySaveThreeDSurfacePlotMainSettingData(settingDataId, scalarBarIsAutoRange,
                                                          scalarBarMin, scalarBarMax, scalarBarIsShowTitle,
                                                          scalarBarTitle, scalarBarFontColor, scalarBarFontSize, geometryTransparency,
                                                          resultGraphName, resultGraphModelTransparency, resultGraphScale, cubeAxesIsVisible);
        }
    }

    void CenterWidget::slot_saveThreeDSurfacePlotMoveResultDataSetting(int windowId, int infomationId, double translationX, double translationY, double translationZ,
                                                                       double rotationTheta, double rotationPhi)
    {
        ThreeDSurfacePlotWindow* graph = getThreeDSurfacePlotWindowByWindowID(windowId);
        if (graph != nullptr)
        {
            graph->pySaveThreeDSurfacePlotMoveResultDataSetting(infomationId, translationX, translationY, translationZ,
                                                                rotationTheta, rotationPhi);
        }
    }

    void CenterWidget::slot_delete3DSurfacePlots(int windowId, QString selectedIndexs)
    {
        ThreeDSurfacePlotWindow* graph = getThreeDSurfacePlotWindowByWindowID(windowId);
        if (graph != nullptr)
        {
            graph->pyDelete3DSurfacePlots(selectedIndexs);
        }
    }

    void CenterWidget::slot_threeDSurfaceCurveNameItemRename(int windowId, int itemIndex, QString newName)
    {
        ThreeDSurfacePlotWindow* graph = getThreeDSurfacePlotWindowByWindowID(windowId);
        if (graph != nullptr)
        {
            graph->pyThreeDSurfaceCurveNameItemRename(itemIndex, newName);
        }
    }

    void CenterWidget::slot_threeDSurfaceCurveDataFileterRadioButtonClicked(int windowId, int index)
    {
        ThreeDSurfacePlotWindow* graph = getThreeDSurfacePlotWindowByWindowID(windowId);
        if (graph != nullptr)
        {
            graph->pyThreeDSurfaceCurveDataFileterRadioButtonClicked(windowId, index);
        }
    }

    void CenterWidget::slot_threeDCloudMapSidebarCurveNameClicked(int windowId, QList<int> selectedIndexes)
    {
        ThreeDCloudMapWindow* graph = getThreeDCloudMapWindowByWindowID(windowId);
        if (graph != nullptr)
        {
            graph->pyCurveNameClicked(selectedIndexes);
        }
    }

    void CenterWidget::slot_threeDCloudMapSidebarUpdateFixedParameter(int windowId, int index)
    {
        ThreeDCloudMapWindow* graph = getThreeDCloudMapWindowByWindowID(windowId);
        if (graph != nullptr)
        {
            graph->pyUpdateFixedParameter(index);
        }
    }

    void CenterWidget::slot_threeDCloudMapSidebarUpdateOriginalDataSource(int windowId, int index, int showType, int fixedValueIndex, bool isLog, bool isNormalize)
    {
        ThreeDCloudMapWindow* graph = getThreeDCloudMapWindowByWindowID(windowId);
        if (graph != nullptr)
        {
            graph->pyUpdateOriginalDataSource(index, showType, fixedValueIndex, isLog, isNormalize);
        }
    }

    void CenterWidget::slot_threeDCloudMapSidebarResultDataChanged(int windowId, int index)
    {
        ThreeDCloudMapWindow* graph = getThreeDCloudMapWindowByWindowID(windowId);
        if (graph != nullptr)
        {
            graph->pyResultDataChanged(index);
        }
    }

    void CenterWidget::slot_threeDCloudMapSidebarNameItemRename(int windowId, int itemIndex, QString newName)
    {
        ThreeDCloudMapWindow* graph = getThreeDCloudMapWindowByWindowID(windowId);
        if (graph != nullptr)
        {
            graph->pyNameItemRename(itemIndex, newName);
        }
    }

    void CenterWidget::slot_threeDCloudMapSidebarDelete3DCloudMap(int windowId, QString selectedIndexs)
    {
        ThreeDCloudMapWindow* graph = getThreeDCloudMapWindowByWindowID(windowId);
        if (graph != nullptr)
        {
            graph->pyDelete3DCloudMap(selectedIndexs);
        }
    }

    void CenterWidget::slot_threeDCloudMapSidebarDataOprationChanged(int windowId, bool isLoged, bool isNormalized)
    {
        ThreeDCloudMapWindow* graph = getThreeDCloudMapWindowByWindowID(windowId);
        if (graph != nullptr)
        {
            graph->pyDataOprationChanged(isLoged, isNormalized);
        }
    }

    void CenterWidget::slot_threeDCloudMapSidebarItemCheckStateChanged(int windowId, int itemIndex, bool visible)
    {
        ThreeDCloudMapWindow* graph = getThreeDCloudMapWindowByWindowID(windowId);
        if (graph != nullptr)
        {
            graph->pyItemCheckStateChanged(itemIndex, visible);
        }
    }

    void CenterWidget::slot_saveThreeDCloudMapMainSettingData(int windowId, int type, int settingDataId, bool scalarBarIsAutoRange,
                                                              double scalarBarMin, double scalarBarMax, bool scalarBarIsShowTitle,
                                                              QString scalarBarTitle, QString scalarBarFontColor, int scalarBarFontSize,
                                                              int geometryTransparency, QString resultGraphName, int resultGraphModelTransparency, bool cubeAxesIsVisible)
    {
        ThreeDCloudMapWindow* graph = getThreeDCloudMapWindowByWindowID(windowId);
        if (graph != nullptr)
        {
            graph->pySaveThreeDCloudMapMainSettingData(type, settingDataId, scalarBarIsAutoRange,
                                                       scalarBarMin, scalarBarMax, scalarBarIsShowTitle,
                                                       scalarBarTitle, scalarBarFontColor, scalarBarFontSize, geometryTransparency,
                                                       resultGraphName, resultGraphModelTransparency, cubeAxesIsVisible);
        }
    }

    void CenterWidget::slot_surfaceElectricFieldMapSidebarCurveNameClicked(int windowId, QList<int> selectedIndexes)
    {
        SurfaceElectricFieldMapWindow* graph = getSurfaceElectricFieldMapWindowByWindowID(windowId);
        if (graph != nullptr)
        {
            graph->pyCurveNameClicked(selectedIndexes);
        }
    }

    void CenterWidget::slot_surfaceElectricFieldMapSidebarResultDataChanged(int windowId, int index)
    {
        SurfaceElectricFieldMapWindow* graph = getSurfaceElectricFieldMapWindowByWindowID(windowId);
        if (graph != nullptr)
        {
            graph->pyResultDataChanged(index);
        }
    }

    void CenterWidget::slot_surfaceElectricFieldMapSidebarUpdateProcessData(int windowId, bool isLog, bool isNormalize)
    {
        SurfaceElectricFieldMapWindow* graph = getSurfaceElectricFieldMapWindowByWindowID(windowId);
        if (graph != nullptr)
        {
            graph->pyUpdateProcessData(isLog, isNormalize);
        }
    }

    void CenterWidget::slot_surfaceElectricFieldMapSidebarNameItemRename(int windowId, int itemIndex, QString newName)
    {
        SurfaceElectricFieldMapWindow* graph = getSurfaceElectricFieldMapWindowByWindowID(windowId);
        if (graph != nullptr)
        {
            graph->pyNameItemRename(itemIndex, newName);
        }
    }

    void CenterWidget::slot_surfaceElectricFieldMapSidebarDeleteSurfaceElectricFieldMap(int windowId, QString selectedIndexs)
    {
        SurfaceElectricFieldMapWindow* graph = getSurfaceElectricFieldMapWindowByWindowID(windowId);
        if (graph != nullptr)
        {
            graph->pyDeleteSurfaceElectricFieldMap(selectedIndexs);
        }
    }

    void CenterWidget::slot_surfaceElectricFieldMapSidebarItemCheckStateChanged(int windowId, int itemIndex, bool visible)
    {
        SurfaceElectricFieldMapWindow* graph = getSurfaceElectricFieldMapWindowByWindowID(windowId);
        if (graph != nullptr)
        {
            graph->pyItemCheckStateChanged(itemIndex, visible);
        }
    }

    void CenterWidget::slot_saveSurfaceElectricFieldMapMainSettingData(int windowId, int type, int settingDataId, bool scalarBarIsAutoRange,
                                                                       double scalarBarMin, double scalarBarMax, bool scalarBarIsShowTitle,
                                                                       QString scalarBarTitle, QString scalarBarFontColor, int scalarBarFontSize,
                                                                       int geometryTransparency, QString resultGraphName, int resultGraphModelTransparency, bool cubeAxesIsVisible)
    {
        SurfaceElectricFieldMapWindow* graph = getSurfaceElectricFieldMapWindowByWindowID(windowId);
        if (graph != nullptr)
        {
            graph->pySaveSurfaceElectricFieldMapMainSettingData(type, settingDataId, scalarBarIsAutoRange,
                                                                scalarBarMin, scalarBarMax, scalarBarIsShowTitle,
                                                                scalarBarTitle, scalarBarFontColor, scalarBarFontSize, geometryTransparency,
                                                                resultGraphName, resultGraphModelTransparency, cubeAxesIsVisible);
        }
    }

    void CenterWidget::slot_savePostMarkerAddSettingData(int windowUniversalID, int infomationGraph3DBasicalId, int type,
                                                         int fieldIndex, QString fieldName, int pickedId, QString pickedValue)
    {
        for (const auto& graph3DWindow : m_graph3DList)
        {
            if (graph3DWindow->getWindowUniversalID() == windowUniversalID)
            {
                graph3DWindow->addMarkerDataInfo(infomationGraph3DBasicalId, type, fieldIndex, fieldName, pickedId,
                                                       pickedValue, nullptr);
            }
        }
    }

    void CenterWidget::slot_savePostMarkerRemoveChosenSettingData(int windowUniversalID, QString removeChosenId)
    {
        for (const auto& graph3DWindow : m_graph3DList)
        {
            if (graph3DWindow->getWindowUniversalID() == windowUniversalID)
            {
                QList<int> removeChosenIds = GlobalHelperInstance->convertStringToIntList(removeChosenId);

                graph3DWindow->removeChosenMarkers(removeChosenIds);
                graph3DWindow->updatePickedDataDisplayWindowVisibility();
            }
        }
    }

    void CenterWidget::slot_savePostMarkerRemoveAllSettingData(int windowUniversalID)
    {
        for (const auto& graph3DWindow : m_graph3DList)
        {
            if (graph3DWindow->getWindowUniversalID() == windowUniversalID)
            {
                graph3DWindow->pyRemoveAllMarker();
            }
        }
    }

    void CenterWidget::slot_savePostMarkerExportTableData(int windowUniversalID, QString fileName)
    {
        for (const auto& graph3DWindow : m_graph3DList)
        {
            if (graph3DWindow->getWindowUniversalID() == windowUniversalID)
            {
                graph3DWindow->pyExportTableData(fileName);
            }
        }
    }

    void CenterWidget::slot_sentWaveButterANdFFTVResult(int windowId, const QList<double>& resultList)
    {
        LineChartWindow* graph = nullptr;
        for (auto i : m_lineChartWindowList)
        {
            if (i.first == windowId)
            {
                graph = i.second;
                break;
            }
        }
        if (graph != nullptr)
        {
            graph->pyShowWaveButterAndFFT(resultList);
        }
    }

    void CenterWidget::setAddedGraphWindowActiveAuto(bool activeAuto)
    {
        m_isActiveAuto = activeAuto;
    }

    bool CenterWidget::getAddedGraphWindowActiveAuto()
    {
        return m_isActiveAuto;
    }

    QTreeView* CenterWidget::getTreeView() const
    {
        return ui->treeView;
    }

    QTabWidget* CenterWidget::getTabWidget()
    {
        return ui->tabWidget;
    }

    Graph2DWindowBase* CenterWidget::addNewGraph2D(GraphType type, int windowUniversalID, int windowID)
    {
        QString tabName;
        Graph2DWindowBase* graph = nullptr;
        int _WindowUniversalID = -1;
        if (windowUniversalID == -1)
        {
            _WindowUniversalID = WindowTotalDataInstance->getWindowUniversalMaxID();
        }
        else
        {
            _WindowUniversalID = windowUniversalID;
        }
        switch (type)
        {
        case pst::GraphType::None:
            break;
        case pst::GraphType::TwoDLineChart:
        {
            tabName = tr("二维折线图");
            int _LineChartWindowMaxID = -1;
            if (windowID == -1)
            {
                _LineChartWindowMaxID = WindowTotalDataInstance->getLineChartWindowMaxID();
            }
            else
            {
                _LineChartWindowMaxID = windowID;
            }
            graph = new LineChartWindow(this, _LineChartWindowMaxID, &infoListLineChartCopy);
            graph->setWindowUniversalID(_WindowUniversalID);
            m_lineChartWindowList.append(qMakePair(_LineChartWindowMaxID, qobject_cast<LineChartWindow*>(graph)));
            connect(qobject_cast<LineChartWindow*>(graph), &LineChartWindow::signal_updateStandardCcurveState, this, &CenterWidget::signal_updateStandardCcurveState);
            connect(qobject_cast<LineChartWindow*>(graph), &LineChartWindow::signal_infoListCopy, this, [this](QList<Info2DPointer>* infoList)
                    { infoListLineChartCopy = *infoList; });
            connect(qobject_cast<LineChartWindow*>(graph), &LineChartWindow::signal_infoListPaste, this, [this]()
                    {
                    emit IWidgetSignalInstance->signal_exitAddMarkerState();
                    if (!infoListLineChartCopy.isEmpty()) {
                        QList<Info2DPointer> infoList;
                        QList<QString> infoIdList;
                        for (const Info2DPointer infoPtr : infoListLineChartCopy)
                        {
                            if (infoPtr)
                            {
                                InfomationCurve2DBasical info = *infoPtr;
                                QSharedPointer<InfomationCurve2DBasical> newInfoPtr = Info2DPointer(new InfomationCurve2DBasical(info));
                                infoList.append(newInfoPtr);
                                infoIdList.append(QString::number(newInfoPtr->getInformationID()));
                            }
                        }

                        QString infoIds = infoIdList.join(",");
                        QString _pyCode = QString("PostProcessing.lineChartCenterWidgetInfoListPaste('%1')").arg(infoIds);
                        emit IBaseSignalInstance->signal_execPYCode(QStringList{_pyCode}, true, false);

                        addImageToNewGrapg2DWindow(infoList, false);
                    } });
            break;
        }
        case pst::GraphType::PolarGraph:
        {
            tabName = tr("极坐标图");
            int _PolarCoordinateGraphWindowMaxID = -1;
            if (windowID == -1)
            {
                _PolarCoordinateGraphWindowMaxID = WindowTotalDataInstance->getPolarCoordinateGraphWindowMaxID();
            }
            else
            {
                _PolarCoordinateGraphWindowMaxID = windowID;
            }
            graph = new PolarCoordinateGraphWindow(this, _PolarCoordinateGraphWindowMaxID);
            graph->setWindowUniversalID(_WindowUniversalID);
            m_polarCoordinateGraphWindowList.append(qMakePair(_PolarCoordinateGraphWindowMaxID, qobject_cast<PolarCoordinateGraphWindow*>(graph)));
            break;
        }
        case pst::GraphType::SurfaceElectricFieldMap:
            break;
        case pst::GraphType::TwoDHeatMap:
        {
            tabName = tr("二维热力图");
            int _HeatMapWindowMaxID = -1;
            if (windowID == -1)
            {
                _HeatMapWindowMaxID = WindowTotalDataInstance->getHeatMapWindowMaxID();
            }
            else
            {
                _HeatMapWindowMaxID = windowID;
            }
            graph = new HeatMapWindow(this, _HeatMapWindowMaxID);
            graph->setWindowUniversalID(_WindowUniversalID);
            m_heatMapWindowList.append(qMakePair(_HeatMapWindowMaxID, qobject_cast<HeatMapWindow*>(graph)));
            break;
        }
        case pst::GraphType::ThreeDCloudMap:
            break;
        case pst::GraphType::ThreeDSurfacePlot:
            break;
        case pst::GraphType::TwoDPeakValleyGraph:
            break;
        default:
            break;
        }
        if (windowID == -1)            
        {
            if (m_tabNameNum.contains(tabName))
            {
                tabName += QString::number(++m_tabNameNum[tabName]);
            }
            else
            {
                m_tabNameNum.insert(tabName, 1);
                tabName += "1";
            }
        }
        else
        {
            m_tabNameNum.insert(tabName, windowID + 1);
            tabName += QString::number(windowID + 1);
        }
        m_graph2DList.append(graph);
        m_graph2DCount++;
        connect(graph, &Graph2DWindowBase::signal_generateANewGraphCurve, this, &CenterWidget::slot_addImageToNewGrapg2DWindow);
        connect(graph, &Graph2DWindowBase::signal_getTwoDResultDataPointer, this, &CenterWidget::signal_getTwoDResultDataPointer);
        connect(graph, &Graph2DWindowBase::signal_updateMeasureButtonState, this, &CenterWidget::signal_updateMeasureButtonState);
        ui->tabWidget->addTab(graph, tabName);
        //ui->tabWidget->setCurrentWidget(graph);
        WindowTotalDataInstance->addGraph2DWindow(graph);
        return graph;
    }

    Graph3DWindowBase* CenterWidget::addNewGraph3D(GraphType type, int windowUniversalID, int windowID)
    {
        QString tabName;
        Graph3DWindowBase* graph = nullptr;
        int _WindowUniversalID = -1;
        if (windowUniversalID == -1)
        {
            _WindowUniversalID = WindowTotalDataInstance->getWindowUniversalMaxID();
        }
        else
        {
            _WindowUniversalID = windowUniversalID;
        }
        switch (type)
        {
        case pst::GraphType::None:
            break;
        case pst::GraphType::TwoDLineChart:
            break;
        case pst::GraphType::PolarGraph:
            break;
        case pst::GraphType::SurfaceElectricFieldMap:
        {
            tabName = tr("表面分布图");
            int _SurfaceElectricFieldMapWindowMaxID = -1;
            if (windowID == -1)
            {
                _SurfaceElectricFieldMapWindowMaxID = WindowTotalDataInstance->getSurfaceElectricFieldMapWindowMaxID();
            }
            else
            {
                _SurfaceElectricFieldMapWindowMaxID = windowID;
            }
            graph = new SurfaceElectricFieldMapWindow(this, _SurfaceElectricFieldMapWindowMaxID);
            graph->setWindowUniversalID(_WindowUniversalID);
            m_surfaceElectricFieldMapWindowList.append(qMakePair(_SurfaceElectricFieldMapWindowMaxID, qobject_cast<SurfaceElectricFieldMapWindow*>(graph)));
            break;
        }
        case pst::GraphType::TwoDHeatMap:
            break;
        case pst::GraphType::ThreeDCloudMap:
        {
            tabName = tr("三维云图 ");
            int _threeDCloudMapId = -1;
            if (windowID == -1)
            {
                _threeDCloudMapId = WindowTotalDataInstance->getThreeDCloudMapWindowMaxID();
            }
            else
            {
                _threeDCloudMapId = windowID;
            }

            graph = new ThreeDCloudMapWindow(this, _threeDCloudMapId);
            graph->setWindowUniversalID(_WindowUniversalID);
            m_threeDCloudMapWindowList.append(qMakePair(_threeDCloudMapId, qobject_cast<ThreeDCloudMapWindow*>(graph)));
            break;
        }
        case pst::GraphType::ThreeDSurfacePlot:
        {
            tabName = tr("三维曲面图 ");
            int _surfacePlotWindowId = -1;
            if (windowID == -1)
            {
                _surfacePlotWindowId = WindowTotalDataInstance->getThreeDSurfacePlotWindowMaxID();
            }
            else
            {
                _surfacePlotWindowId = windowID;
            }
            graph = new ThreeDSurfacePlotWindow(this, _surfacePlotWindowId);
            graph->setWindowUniversalID(_WindowUniversalID);
            m_surfacePlotWindowList.append(qMakePair(_surfacePlotWindowId, qobject_cast<ThreeDSurfacePlotWindow*>(graph)));
            break;
        }
        case pst::GraphType::TwoDPeakValleyGraph:
            break;
        default:
            break;
        }
        if (windowID == -1)
        {
            if (m_tabNameNum.contains(tabName))
            {
                tabName += QString::number(++m_tabNameNum[tabName]);
            }
            else
            {
                m_tabNameNum.insert(tabName, 1);
                tabName += "1";
            }
        }
        else
        {
            m_tabNameNum.insert(tabName, windowID + 1);
            tabName += QString::number(windowID + 1);
        }

        if (graph == nullptr)
        {
            return nullptr;
        }
        m_graph3DList.append(graph);
        m_graph2DCount++;
        WindowTotalDataInstance->addGraph3DWindow(graph);
        ui->tabWidget->addTab(graph, tabName);
        return graph;
    }

    // GraphSurface* CenterWidget::addNewGraphSurface()
    //{
    //     GraphSurface* graph = new GraphSurface(this);
    //     //m_graph3DList.append(graph);
    //     m_graph2DCount++;
    //     ui->tabWidget->addTab(graph, QString::number(m_graph2DCount));
    //     return graph;
    // }

    void CenterWidget::addImageToGraph3DWindow(QList<InfomationGraph3DBasical*>& infos, bool useNewWindow)
    {
        Graph3DWindowBase* graph{nullptr};

        if (useNewWindow)
        {
            if (!infos.isEmpty())
            {
                graph = addNewGraph3D(infos.at(0)->m_graphType);
            }
        }
        else
        {
            graph = qobject_cast<Graph3DWindowBase*>(ui->tabWidget->currentWidget());
        }
        if (graph == nullptr)
        {
            emit IBaseSignalInstance->signal_sendErrorMessageToUI("图像类型不匹配");
            return;
        }

        if (m_isActiveAuto)
        {
            ui->tabWidget->setCurrentWidget(graph);
        }

        for (auto& i : infos)
        {
            i->m_graph = graph;
            addImageToGraph3D(i);
        }
        //添加完数据后再刷新一次，满足 根据添加到窗口后的数据来判断状态的需求，如雷电分区按钮是否可用
        emit signal_currentWindowChanged();
    }

    void CenterWidget::addImageToGraph3D(InfomationGraph3DBasical* info)
    {
        if (info->m_graph == nullptr)
        {
            return;
        }
        //info->m_graph->setAnimationSettingData(m_animationSettingData);
        info->m_graph->addGraph3D(info);
    }

    Graph3DWindowBase* CenterWidget::getGraph3DWindowBaseByUniversalID(int windowUniversalID)
    {
        for (const auto& graph3DWindow : m_graph3DList)
        {
            if (graph3DWindow->getWindowUniversalID() == windowUniversalID)
            {
                return graph3DWindow;
            }
        }
        return nullptr;
    }

    // void CenterWidget::addImageToNewSurfaceWindow(const QString& fileName)
    //{
    //     GraphSurface* graph = addNewGraphSurface();
    //     if (m_isActiveAuto)
    //     {
    //         ui->tabWidget->setCurrentWidget(graph);
    //     }
    //     graph->addSurfaceActor(fileName);
    // }

    void CenterWidget::addDataToTableWindow(InfomationGraph3DBasical* info, bool useNewWindow, int windowUniversalID, int windowID)
    {
        if (useNewWindow)
        {
            int _WindowUniversalID = -1;
            int _tableChatWindowMaxID = -1;
            if (windowUniversalID == -1)
            {
                _WindowUniversalID = WindowTotalDataInstance->getWindowUniversalMaxID();
                _tableChatWindowMaxID = WindowTotalDataInstance->getTableChatWindowMaxID();
            }
            else
            {
                _WindowUniversalID = windowUniversalID;
                _tableChatWindowMaxID = windowID;
            }          
            TableChatWindow* tableChatWindow = new TableChatWindow(this);
            tableChatWindow->setWindowID(_tableChatWindowMaxID);
            tableChatWindow->setWindowUniversalID(_WindowUniversalID);
            WindowTotalDataInstance->addGraph3DWindow(tableChatWindow);
            ui->tabWidget->addTab(tableChatWindow, QStringLiteral("表格") + QString::number(_tableChatWindowMaxID+1));
            ui->tabWidget->setCurrentWidget(tableChatWindow);
            tableChatWindow->addDataToWindow(info);
            tableChatWindow->setTableDataInfo();
            tableChatWindow->setTableDataSource(info->m_dataSources);
            tableChatWindow->addDataFilterVarItem();
            m_tableWindowList.append(qMakePair(_tableChatWindowMaxID, qobject_cast<TableChatWindow*>(tableChatWindow)));
        }
    }

    void CenterWidget::pyHideOrShowTableColumn(int windowId, QString selectedIndex)
    {
        TableChatWindow* tableChatWindow = getTableChatWindowByWindowId(windowId);
        QSet<int> set;
        QStringList list = selectedIndex.split('_');
        for (QString v : list)
        {
            set.insert(v.toInt());
        }
        tableChatWindow->pyHideOrShowTableColumn(set);
    }

    void CenterWidget::pyChangeTbColumnName(int windowId, int index, QString newName)
    {
        TableChatWindow* tableChatWindow = getTableChatWindowByWindowId(windowId);
        tableChatWindow->pyRenameColName(index, newName);
    }

    void CenterWidget::pyFlushTbBySelectedRow(int windowId, QString parms)
    {
        TableChatWindow* tableChatWindow = getTableChatWindowByWindowId(windowId);
        tableChatWindow->pyFlushTableBySelectedRow(parms);
    }

    void CenterWidget::pyExportTbData(int windowId, QString filePath, QString delimiter, int onlyVisible)
    {
        TableChatWindow* tableChatWindow = getTableChatWindowByWindowId(windowId);
        bool _onlyVisible = onlyVisible ? 1 : 0;
        tableChatWindow->exportTableData(filePath, delimiter[0], _onlyVisible, false);
    }

    void CenterWidget::pyHighlightSelectedTbColumns(int windowId, QString parms)
    {
        TableChatWindow* tableChatWindow = getTableChatWindowByWindowId(windowId);
        tableChatWindow->pyHighlightSelectedTbColumns(parms);
    }

    TableChatWindow* CenterWidget::getTableChatWindowByWindowId(int windowId)
    {
        for (auto windowPair : m_tableWindowList)
        {
            if (windowPair.first == windowId)
            {
                return windowPair.second;
            }
        }
        return nullptr;
    }

    // void CenterWidget::setCurrentTab(Graph2D* _graph2D)
    //{
    //     ui->tabWidget->setCurrentWidget(_graph2D);
    // }

    int CenterWidget::getItemDepth(const QStandardItem* item)
    {
        if (!item)
            return 0;

        int depth = 0;
        QStandardItem* parent = item->parent();
        while (parent)
        {
            ++depth;
            parent = parent->parent();
        }
        return depth;
    }

    QList<QStandardItem*> CenterWidget::getSubtreeByItem(const QStandardItem* item)
    {
        QList<QStandardItem*> items;
        if (!item)
            return items;
        std::function<void(const QStandardItem*)> collect = [&](const QStandardItem* node)
        {
            QStandardItem* newItem = node->clone();

            items.append(const_cast<QStandardItem*>(node)); // 加入当前节点

            for (int i = 0; i < node->rowCount(); ++i)
            {
                QStandardItem* child = node->child(i); // 默认取 column 0
                if (child)
                    collect(child);
            }
        };
        collect(item);
        return items;
    }
    QList<QStandardItem*> CenterWidget::getLeafsByItem(const QStandardItem* item)
    {
        QList<QStandardItem*> items;
        if (!item)
            return items;
        std::function<void(const QStandardItem*)> collect = [&](const QStandardItem* node)
        {

            if (!node->hasChildren())//叶子节点
            {
                items.append(const_cast<QStandardItem*>(node)); // 加入当前节点
            }

            for (int i = 0; i < node->rowCount(); ++i)
            {
                QStandardItem* child = node->child(i); // 默认取 column 0
                if (child)
                    collect(child);
            }
        };
        collect(item);
        return items;
    }
    QStandardItem* CenterWidget::deepCopyItem(const QStandardItem* source, const std::function<void(QStandardItem* copied, const QStandardItem* original)>& onCopy)
    {
        if (!source)
            return nullptr;
        // 1. 克隆当前节点（不包含子节点）
        QStandardItem* newItem = source->clone();
        newItem->setData(ProjectTreeDataInstance->generateProjectTreeItemID(), Qt::UserRole + 10);

        auto _data = newItem->data(Qt::UserRole + 10).toInt();
        // 2. 调用用户提供的处理函数
        if (onCopy)
            onCopy(newItem, source);
        // 3. 递归克隆所有子节点
        for (int row = 0; row < source->rowCount(); ++row)
        {
            // 如果你只用了 appendRow，说明只有 column 0 有数据
            const QStandardItem* childSource = source->child(row);
            if (childSource)
            {
                QStandardItem* childCopy = deepCopyItem(childSource, onCopy);
                newItem->appendRow(childCopy);
            }
        }
        return newItem;
    }
    QString CenterWidget::getPasteItemText(const QStandardItem* item, const QStandardItem* parent)
    {
        QString decorateStr = "复制";
        QString text = item->text();
        QString pattern = QString("^%1_%2_([0-9]+)$")
            .arg(QRegularExpression::escape(text))
            .arg(QRegularExpression::escape(decorateStr));
        QRegularExpression reg(pattern);

        bool currentDirNotThisName = true;
        int maxNumber = 0;
        for (int row = 0; row < parent->rowCount(); ++row)
        {
            const QStandardItem* child = parent->child(row);
            QString str = child->text();
            QRegularExpressionMatch match = reg.match(str);
            if (child)
            {
                if (match.hasMatch())
                {
                    QString numberStr = match.captured(1);
                    int number = numberStr.toInt();
                    maxNumber = std::max(maxNumber, number);
                }
                if (str == text)
                {
                    currentDirNotThisName = false;
                }
            }
        }

        if (currentDirNotThisName)
        {
            return text;
        }

        maxNumber++;
        return QString("%1_%2_%3")
            .arg(text)
            .arg(decorateStr)
            .arg(QString::number(maxNumber));
    }

    void CenterWidget::traverseTreeView(QModelIndex& parent, int depth)
    {
        if (!treeModel)
            return;

        int rowCount = treeModel->rowCount(parent);
        for (int row = 0; row < rowCount; ++row)
        {
            QModelIndex index = treeModel->index(row, 0, parent); // 假设只遍历第一列
            QStandardItem* item = treeModel->itemFromIndex(index);
            auto itemId = item->data(Qt::UserRole + 10).toInt();
            m_treeItemMap.insert(itemId, item);

            // 递归遍历子项
            if (treeModel->hasChildren(index))
            {
                traverseTreeView(index, depth + 1);
            }
        }
    }

    void CenterWidget::saveCollapseOrExpandPyCode(bool expand, int itemId)
    {
        if (m_treeItemMap.isEmpty() || m_needFlushItemMap)
        {
            traverseTreeView(QModelIndex(), 0);
            m_needFlushItemMap = false;
        }

        QStringList _pyCodes{};
        _pyCodes += QString("appPrj = PostProcessing.AppPrj()");

        if (expand)
        {
            _pyCodes += QString("appPrj.doPrjTreeExpandDir(%1)").arg(itemId);
        }
        else
        {
            _pyCodes += QString("appPrj.doPrjTreeCollapseDir(%1)").arg(itemId);
        }
        emit IBaseSignalInstance->signal_execPYCode(_pyCodes, true, false);
    }

} // namespace pst
